Obfuscate sensitive preference data from the back-up

CURA-7180 keyring storage
This commit is contained in:
Jelle Spijker 2021-03-17 08:54:16 +01:00
parent b6b9dd1864
commit 3fd3fd7c7d
No known key found for this signature in database
GPG Key ID: 6662DC033BE6B99A

View File

@ -5,6 +5,7 @@ import io
import os import os
import re import re
import shutil import shutil
from copy import deepcopy
from zipfile import ZipFile, ZIP_DEFLATED, BadZipfile from zipfile import ZipFile, ZIP_DEFLATED, BadZipfile
from typing import Dict, Optional, TYPE_CHECKING from typing import Dict, Optional, TYPE_CHECKING
@ -27,6 +28,9 @@ class Backup:
IGNORED_FILES = [r"cura\.log", r"plugins\.json", r"cache", r"__pycache__", r"\.qmlc", r"\.pyc"] IGNORED_FILES = [r"cura\.log", r"plugins\.json", r"cache", r"__pycache__", r"\.qmlc", r"\.pyc"]
"""These files should be ignored when making a backup.""" """These files should be ignored when making a backup."""
SECRETS_SETTINGS = ["general/ultimaker_auth_data"]
"""Secret preferences that need to obfuscated when making a backup of Cura"""
catalog = i18nCatalog("cura") catalog = i18nCatalog("cura")
"""Re-use translation catalog""" """Re-use translation catalog"""
@ -43,6 +47,9 @@ class Backup:
Logger.log("d", "Creating backup for Cura %s, using folder %s", cura_release, version_data_dir) Logger.log("d", "Creating backup for Cura %s, using folder %s", cura_release, version_data_dir)
# obfuscate sensitive secrets
secrets = self._obfuscate()
# Ensure all current settings are saved. # Ensure all current settings are saved.
self._application.saveSettings() self._application.saveSettings()
@ -78,6 +85,8 @@ class Backup:
"profile_count": str(profile_count), "profile_count": str(profile_count),
"plugin_count": str(plugin_count) "plugin_count": str(plugin_count)
} }
# Restore the obfuscated settings
self._illuminate(**secrets)
def _makeArchive(self, buffer: "io.BytesIO", root_path: str) -> Optional[ZipFile]: def _makeArchive(self, buffer: "io.BytesIO", root_path: str) -> Optional[ZipFile]:
"""Make a full archive from the given root path with the given name. """Make a full archive from the given root path with the given name.
@ -134,6 +143,9 @@ class Backup:
"Tried to restore a Cura backup that is higher than the current version.")) "Tried to restore a Cura backup that is higher than the current version."))
return False return False
# Get the current secrets and store since the back-up doesn't contain those
secrets = self._obfuscate()
version_data_dir = Resources.getDataStoragePath() version_data_dir = Resources.getDataStoragePath()
archive = ZipFile(io.BytesIO(self.zip_file), "r") archive = ZipFile(io.BytesIO(self.zip_file), "r")
extracted = self._extractArchive(archive, version_data_dir) extracted = self._extractArchive(archive, version_data_dir)
@ -146,6 +158,9 @@ class Backup:
Logger.log("d", "Moving preferences file from %s to %s", backup_preferences_file, preferences_file) Logger.log("d", "Moving preferences file from %s to %s", backup_preferences_file, preferences_file)
shutil.move(backup_preferences_file, preferences_file) shutil.move(backup_preferences_file, preferences_file)
# Restore the obfuscated settings
self._illuminate(**secrets)
return extracted return extracted
@staticmethod @staticmethod
@ -173,3 +188,28 @@ class Backup:
Logger.logException("e", "Unable to extract the backup due to permission or file system errors.") Logger.logException("e", "Unable to extract the backup due to permission or file system errors.")
return False return False
return True return True
def _obfuscate(self) -> Dict[str, str]:
"""
Obfuscate and remove the secret preferences that are specified in SECRETS_SETTINGS
:return: a dictionary of the removed secrets. Note: the '/' is replaced by '__'
"""
preferences = self._application.getPreferences()
secrets = {}
for secret in self.SECRETS_SETTINGS:
secrets[secret.replace("/", "__")] = deepcopy(preferences.getValue(secret))
preferences.setValue(secret, None)
self._application.savePreferences()
return secrets
def _illuminate(self, **kwargs) -> None:
"""
Restore the obfuscated settings
:param kwargs: a dict of obscured preferences. Note: the '__' of the keys will be replaced by '/'
"""
preferences = self._application.getPreferences()
for key, value in kwargs.items():
preferences.setValue(key.replace("__", "/"), value)
self._application.savePreferences()