Some code organisation and recovery procedure fix

This commit is contained in:
2024-12-09 23:23:11 +01:00
parent 5f08435816
commit 3acafaea32
7 changed files with 305 additions and 234 deletions

View File

@@ -19,43 +19,120 @@ from .PyqcrmFlags import PyqcrmFlags
class ConfigLoader(QObject):
__config = None
__version = "0.1-alpha"
__check_enc_key = True
dbConnectionError = Signal(str, bool)
adminUserError = Signal(str, bool)
usernameNotAvailable = Signal()
configurationReady = Signal(bool)
adminNotAvailable = Signal()
configurationReady = Signal()
backupEncryptionKey = Signal()
invalidEncryptionKey = Signal()
def __init__(self):
super().__init__()
self.config_dir = user_config_dir() + '/pyqcrm' #user_config_dir = Funktion platformdirs
# print(f"In {__file__} file, __init__()")
self.config_dir = user_config_dir() + '/pyqcrm'
config_dir = Path(self.config_dir)
if config_dir.exists():
self.__configLoad()
if self.__config:
self.checkEncryptionKey()
else:
config_dir.mkdir(0o750, True, True)
@Slot(dict, result= bool)
def setConfig(self, app_config):
# print(f"In {__file__} file, setConfig()")
if not self.__config:
base_conf = self.__initializeConfig()
conf = self.__checkDbConnection(app_config)
app_config = toml.dumps(app_config)
if conf:
app_config = base_conf + app_config
self.__config = toml.loads(app_config)
self.__saveConfig()
conf = self.__checkAdminUser()
if conf:
self.configurationReady.emit()
def __initializeConfig(self):
# print(f"In {__file__} file, __initializeConfig()")
self.__encrypt_key = b64encode(get_random_bytes(32)).decode("utf-8")
conf = f"[pyqcrm]\nVERSION = \"{self.__version}\"\n"
conf = conf + f"ENCRYPTION_KEY_VALID = \"No\"\n"
conf = conf + f"ENCRYPTION_KEY = \"{self.__encrypt_key}\"\n\n"
return conf
def __checkDbConnection(self, db_config):
# print(f"In {__file__} file, __checkDbConnection()")
con = DbManager(db_config['database']).getConnection()
if con:
self.dbConnectionError.emit("Connection OK", True)
return True
else:
self.dbConnectionError.emit("Connection fehlgeschlagen", False)
return False
def __saveConfig(self):
# print(f"In {__file__} file, saveConfig()")
try:
with open (self.config_dir + '/pyqcrm.toml', 'w') as f:
# print(self.__config)
config = Vermasseln().oscarVermasseln(toml.dumps(self.__config))
f.write(config)
except FileNotFoundError:
print("Konnte die Konfiguration nicht speichern.")
def __checkAdminUser(self):
# print(f"In {__file__} file, __checkAdminUser()")
con = DbManager().getConnection()
cur = con.cursor()
cur.callproc("checkAdmin")
result = cur.fetchall()
if not result:
#if not result[0][0] == 1:
self.adminUserError.emit("Kein Admin vorhanden", False)
return False
else:
self.adminUserError.emit("Admin vorhanden", True)
return True
@Slot(dict, result= bool)
def addAdminUser(self, user_config):
# print(f"In {__file__} file, addAdminUser()")
admin = UserManager(user_config["user"], PyqcrmFlags.ADMIN).createUser()
if not admin:
#self.adminNotAvailable.emit()
self.adminUserError.emit("Benutzername nich verfügbar", False)
else:
self.__config['pyqcrm']['ENCRYPTION_KEY_VALID'] = 'Yes'
self.__saveConfig()
self.backupEncryptionKey.emit()
return admin
@Slot(str, str)
def saveRecoveryKey(self, recovery_file, recovery_password):
# print(f"In {__file__} file, saveRecoveryKey()")
rp = self.__setRecoveryPassword(recovery_password)
rf = rp[1] + self.__encrypt_key + rp[0]
rf = Vermasseln().oscarVermasseln(rf)
rec_file = urlparse(recovery_file)
rec_file = rec_file.path
rec_file = rec_file.path + ".pyqrec"
if os.name == "nt":
rec_file = rec_file [1:]
try:
with open(rec_file, "w") as f:
f.write(rf)
self.configurationReady.emit(True)
self.configurationReady.emit()
except Exception as e:
print(str(e))
@Slot(str, str)
def getRecoveryKey(self, recovery_file, recovery_password):
# print(f"In {__file__} file, getRecoveryKey()")
rec_file = urlparse(recovery_file)
rec_file = rec_file.path
if os.name == "nt":
@@ -70,21 +147,33 @@ class ConfigLoader(QObject):
salt = rf[-32:]
ok = self.__checkRecoveryPassword(recovery_password, password, salt)
if ok:
self.configurationReady.emit(True)
self.__setEncryptionKey(ek)
self.configurationReady.emit()
else:
self.configurationReady.emit(False)
self.__invalidateEncryptionKey()
self.invalidEncryptionKey.emit()
except Exception as e:
print(str(e))
def __invalidateEncryptionKey(self):
# print(f"In {__file__} file, __invalidateEncryptionKey()")
self.__config['pyqcrm']['ENCRYPTION_KEY_VALID'] = 'No'
self.__saveConfig()
@Slot()
def checkEncryptionKey(self):
# print(f"In {__file__} file, __checkEncryptionKey()")
if self.__config['pyqcrm']['ENCRYPTION_KEY_VALID'] == 'No':
self.invalidEncryptionKey.emit()
def __checkRecoveryPassword(self, recovery_password, password, salt):
# print(f"In {__file__} file, __checkRecoveryPassword()")
rp = self.__setRecoveryPassword(recovery_password, salt)
return rp[1] == password
@Slot(str, str)
def importConfig(self, confile, password):
# print(f"In {__file__} file, importConfig()")
confile = urlparse(confile)
confile = confile.path
@@ -92,38 +181,13 @@ class ConfigLoader(QObject):
confile = confile[1:]
shutil.copyfile(confile, self.config_dir+ '/pyqcrm.toml')
@Slot(dict, result= bool)
def addAdminUser(self, user_config):
admin = UserManager(user_config["user"], PyqcrmFlags.ADMIN).createUser()
if not admin:
self.usernameNotAvailable.emit()
else:
self.backupEncryptionKey.emit()
return admin
@Slot(dict, result= bool)
def setConfig(self, app_config):
base_conf = self.__initializeConfig()
conf = self.__checkDbConnection(app_config)
app_config = toml.dumps(app_config)
if conf:
app_config = base_conf + app_config
self.__config = toml.loads(app_config)
self.__saveConfig()
conf = self.__checkAdminUser()
if conf:
self.configurationReady.emit(True)
def __configLoad(self):
# print(f"In {__file__} file, __configLoad()")
try:
with open (self.config_dir + '/pyqcrm.toml', 'r') as f:
config = f.read()
self.__config = toml.loads(Vermasseln().entschluesseln(config))
self.configurationReady.emit(True)
self.configurationReady.emit()
except FileNotFoundError:
print("Konnte die Konfiguration nicht laden.")
except TypeError:
@@ -131,50 +195,20 @@ class ConfigLoader(QObject):
except Exception as e:
print(str(e))
def getConfig(self):
# print(f"In {__file__} file, getConfig()")
# print(self.__config)
return self.__config
def __initializeConfig(self):
self.__encrypt_key = b64encode(get_random_bytes(32)).decode("utf-8")
conf = f"[pyqcrm]\nVERSION = \"{self.__version}\"\nENCRYPTION_KEY = \"{self.__encrypt_key}\"\n\n"
return conf
def __checkDbConnection(self, db_config):
con = DbManager(db_config['database']).getConnection()
if con:
self.dbConnectionError.emit("Connection OK", True)
return True
else:
self.dbConnectionError.emit("Connection fehlgeschlagen", False)
return False
def __checkAdminUser(self):
con = DbManager().getConnection()
cur = con.cursor()
cur.callproc("checkAdmin")
result = cur.fetchall()
if not result:
#if not result[0][0] == 1:
self.adminUserError.emit("Kein Admin vorhanden", False)
return False
else:
self.adminUserError.emit("Admin vorhanden", True)
return True
def __setRecoveryPassword(self, key, salt = None):
# print(f"In {__file__} file, __setRecoveryPassword()")
key = Vermasseln.userPasswordHash(key, salt)
return key.split("$")
def __saveConfig(self):
try:
with open (self.config_dir + '/pyqcrm.toml', 'w') as f:
config = Vermasseln().oscarVermasseln(toml.dumps(self.__config))
f.write(config)
except FileNotFoundError:
print("Konnte die Konfiguration nicht speichern.")
@Slot(str)
def __setEncryptionKey(self, enc_key):
# print(f"In {__file__} file, __setEncryptionKey()")
self.__config['pyqcrm']['ENCRYPTION_KEY_VALID'] = 'Yes'
self.__config['pyqcrm']['ENCRYPTION_KEY'] = enc_key
self.__saveConfig()