From 5bf35ce12a171244259ce9d5845dcea6c0e09eda72d3636bc8452cbd41e7920d Mon Sep 17 00:00:00 2001 From: Marco Gatzen Date: Mon, 2 Dec 2024 16:15:26 +0100 Subject: [PATCH] Login, user in datenbank und encryption key --- Gui/AdminUserConfig.qml | 14 ++ Gui/TopBar.qml | 1 + Gui/firststart.qml | 12 +- lib/ConfigLoader.py | 18 +- lib/DB/UserManager.py | 23 ++- lib/Vermasseln.py | 18 +- rc_TopBarModule.py | 78 -------- rc_pyqcrm.py | 32 +-- rc_qml.py | 422 ++++++++++++++++++++-------------------- 9 files changed, 309 insertions(+), 309 deletions(-) delete mode 100644 rc_TopBarModule.py diff --git a/Gui/AdminUserConfig.qml b/Gui/AdminUserConfig.qml index 5d9a3ca..04a2353 100644 --- a/Gui/AdminUserConfig.qml +++ b/Gui/AdminUserConfig.qml @@ -24,6 +24,7 @@ GridLayout Label { + id: benutzerNamelabel text: qsTr("Benutzername:") Layout.alignment: Qt.AlignRight } @@ -69,4 +70,17 @@ GridLayout { Layout.fillHeight: true } + Component.onCompleted: + { + config.usernameNotAvailable.connect(usernameNotAvailable) + } + function usernameNotAvailable() + { + benutzerName.placeholderText = qsTr ("Benutzername ist bereits vergeben") + benutzerName.clear() + benutzerNamelabel.color = "red" + benutzerNamelabel.font.bold = true + } } + + diff --git a/Gui/TopBar.qml b/Gui/TopBar.qml index be1149f..f75dadd 100644 --- a/Gui/TopBar.qml +++ b/Gui/TopBar.qml @@ -37,6 +37,7 @@ RowLayout implicitWidth: kunden.implicitContentWidth + 10 onClicked: { + // TODO: here we should call the model appLoader.source = "CustomerTables.qml" } } diff --git a/Gui/firststart.qml b/Gui/firststart.qml index e6d81f9..fe75225 100644 --- a/Gui/firststart.qml +++ b/Gui/firststart.qml @@ -45,7 +45,6 @@ Item firstStart.push("AdminUserConfig.qml") } - MessageDialog { id: conErrDialog @@ -62,7 +61,13 @@ Item title: qsTr("Encryption Key") anchors.centerIn: parent standardButtons: Dialog.Ok | Dialog.Cancel - onAccepted: config.setEncyrptKey(encryptPassword.text) + onAccepted: + { + // TODO: signal for EncryptionKey testing + config.setEncyrptKey(encryptPassword.text) + appLoader.source = "Dashboard.qml" + topBar.visible = true + } ColumnLayout { RowLayout @@ -89,6 +94,7 @@ Item id: firstStart anchors.fill: parent initialItem: "DbConfiguration.qml" + //initialItem: "AdminUserConfig.qml" } RowLayout { @@ -126,7 +132,7 @@ Item pyqcrm_conf = Qmldict.func(submitBtn.grids) if (pyqcrm_conf) { - admin = config.setConfig(pyqcrm_conf) + config.setConfig(pyqcrm_conf) } } diff --git a/lib/ConfigLoader.py b/lib/ConfigLoader.py index 045851d..99fd28b 100644 --- a/lib/ConfigLoader.py +++ b/lib/ConfigLoader.py @@ -15,6 +15,7 @@ from .PyqcrmFlags import PyqcrmFlags + class ConfigLoader(QObject): __config = None __version = "0.1-alpha" @@ -22,6 +23,7 @@ class ConfigLoader(QObject): dbConnectionError = Signal(str, bool) adminUserError = Signal(str, bool) + usernameNotAvailable = Signal() def __init__(self): super().__init__() @@ -46,7 +48,10 @@ class ConfigLoader(QObject): @Slot(dict, result= bool) def addAdminUser(self, user_config): admin = UserManager(user_config["user"], PyqcrmFlags.ADMIN).createUser() - return True + print (admin) + if not admin: + self.usernameNotAvailable.emit() + return admin @Slot(dict, result= bool) def setConfig(self, app_config): @@ -93,12 +98,21 @@ class ConfigLoader(QObject): 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) + else: + self.adminUserError.emit("Admin vorhanden", True) - self.adminUserError.emit("Kein Admin vorhanden", False) @Slot(str) def setEncyrptKey(self, key): self.__config['pyqcrm']['ENCRYPTION_KEY'] = key + print(self.__config) self.__saveConfig() def __saveConfig(self): diff --git a/lib/DB/UserManager.py b/lib/DB/UserManager.py index 865ccd2..f09ad3b 100644 --- a/lib/DB/UserManager.py +++ b/lib/DB/UserManager.py @@ -1,5 +1,7 @@ from .DbManager import DbManager from ..PyqcrmFlags import PyqcrmFlags +from ..Vermasseln import Vermasseln +import mariadb @@ -15,9 +17,24 @@ class UserManager(): def createUser(self): - self.__cur.callproc("createUser", (self.__username, self.__password, self.__info, self.__role)) - self.__con.commit() - self.__closeConnection() + self.__hashPassword() + user_created = True + try: + self.__cur.callproc("createUser", (self.__username, self.__password, self.__info, self.__role)) + self.__con.commit() + except mariadb.Error as e: + print(f"Error: {e}") + print(e.errno) + user_created = False + finally: + self.__cur.close() + #self.__closeConnection() + return user_created + + def __hashPassword(self): + self.__password = Vermasseln.userPasswordHash(self.__password) + print (self.__password) + def getUser(self): self.__closeConnection() diff --git a/lib/Vermasseln.py b/lib/Vermasseln.py index cf0ae44..04ca19f 100644 --- a/lib/Vermasseln.py +++ b/lib/Vermasseln.py @@ -2,7 +2,11 @@ from Crypto.Cipher import AES from base64 import b64encode, b64decode import platform -from Crypto.Hash import SHA256 +from Crypto.Hash import SHA256, SHA3_512 +from Crypto.Protocol.KDF import PBKDF2 +from Crypto.Random import get_random_bytes +import random +import string class Vermasseln: @@ -42,6 +46,18 @@ class Vermasseln: cipher = AES.new(hashed, AES.MODE_SIV, nonce = nonce) return cipher + @classmethod + def userPasswordHash(self, password): + + salt = "".join(random.choice(string.ascii_letters + string.digits) for i in range (32)) + hash_pw = (salt + password).encode("utf-8") + h_obj = SHA3_512.new(hash_pw) + password = salt + "$" + h_obj.hexdigest() + + return password + + + diff --git a/rc_TopBarModule.py b/rc_TopBarModule.py deleted file mode 100644 index 4dcf411..0000000 --- a/rc_TopBarModule.py +++ /dev/null @@ -1,78 +0,0 @@ -# Resource object code (Python 3) -# Created by: object code -# Created by: The Resource Compiler for Qt version 6.8.0 -# WARNING! All changes made in this file will be lost! - -from PySide6 import QtCore - -qt_resource_data = b"\ -\x00\x00\x01\xba\ -(\ -\xb5/\xfd`\xdd\x04\x85\x0d\x00\xb6\x13=\x1f0s\x1e\ -\xb3\xfb\x92H\xd4\xdc\x08\xd0\xcdc\xdb\xa9\xa2\xa0\xc4\xa4\ -\xbco\x17:w\xe6&\x14T4\x0c\x034\x003\x00\ -4\x00{5\x07\x9f\x8a\x9d\x83\xa1\xb9\x87UdHh\ -\xae\x9a\xf1\xedE}\x17W\x7fsTl\x0c\xc4:]\ -a\x8c~\xed\xcfF\xa8l\xff\xd9\x0c\x89i^\xac\x94\ -\xa7\xb4\xf7\xbe\xac\x18M(4A\x9b,]>\xbe(\ -/+\x10M\x90n#\x02\xb8\x85n\x9a{\x0fs\xf5\ -o\xeeWb(\xdf^@\xba\xd4\xec\xff\xba\x081\xf6\ -\x18\x96\xd4\x1b\xbe\xb9\xd2O\xf6\x8f}Z\xfe\xb4C\xe2\ -\xfc\x91'\xdf\x8f\xd6\xe45\x9c\x99\x9a\xb2\x9c\xd6\xe2l\ -\xf5\xd3\xca\x80L\xa6f\xd5\x84\x22im\xa4\x96h\xfc\ -\xbc6\x95\x9c\xa9\xed\xc8u9\x8a5\x8c\x19\x8c\x85\x10\ -\xcd\xcdX\xf9J\x1eV\xd1#\x8a\xdd[\xf6\x8b*\x0e\ -\x95\xeadk@\xb9Z+\x0e\xdc\xf3M\xd4\xdc\xecG\ -;\xb3/e\xc4Ho/\x0a-\xfe\x87\xa2\x9au\xc2\ -N\xa0\x91\x1dB\x8a!\x91))LZ\x03@\x84\x18\ -\xc6\xec\x1c\x03\x00\xb53i!-\xd8t\x01r\x1e\xc8\ -R\xc2\x99\x15\xe6\xba7\xf5\xb1\x85]\xd9d4\xe6\x0c\ -\x07\x95\x88^\xe0\xf7\x96\x0d\xeb\xc7\xa2\xaeQ\xbf\x96\xfd\ -\x93\x9c\xd3\x1cX\x94L7\x1bB\xb5\xb0\xc2tNJ\ -\x5c\xf0x\x18\x1d\xd3vQ\x82w\xa5\xf6\x18\xb9\xbb\xaa\ -\x8d)z\x08\x8f\xf5\xb8\x80\xe7*\xab\xbd\x0f\xd2\x92;\ -\xc4\xaa@\x8bdyf\xa1\x0d\xc2[\xc6\xa0QD\x18\ -\x97p\xb1\x85\xf3m3\x04\x05\x95=^\xd8SU\xe5\ -6\x9e\x93%!~\x0d`\x01_\xdb(\x5c\xa0\xa7\x82\ -\x03\xf0\xd6\xb8\x0d\x97\xd8n\x056\x87\xb4\xaf%\xb4\x0d\ -\x83\xfb\x1b\xe6\x8aD\x22w*\ -\x00\x00\x00$\ -m\ -odule TopBar\x0aTop\ -Bar 1.0 TopBar.q\ -ml\x0a\ -" - -qt_resource_name = b"\ -\x00\x03\ -\x00\x00n\xb9\ -\x00g\ -\x00u\x00i\ -\x00\x0a\ -\x08\x8e<\xbc\ -\x00T\ -\x00o\x00p\x00B\x00a\x00r\x00.\x00q\x00m\x00l\ -\x00\x06\ -\x07\x84+\x02\ -\x00q\ -\x00m\x00l\x00d\x00i\x00r\ -" - -qt_resource_struct = b"\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ -\x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\ -\x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00&\x00\x00\x00\x00\x00\x01\x00\x00\x01\xbe\ -\x00\x00\x01\x93+<\x17\x5c\ -\x00\x00\x00\x0c\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x01\x93*\xc9x\xab\ -" - -def qInitResources(): - QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) - -def qCleanupResources(): - QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) - -qInitResources() diff --git a/rc_pyqcrm.py b/rc_pyqcrm.py index 2f4738f..5b64a64 100644 --- a/rc_pyqcrm.py +++ b/rc_pyqcrm.py @@ -6,10 +6,10 @@ from PySide6 import QtCore qt_resource_data = b"\ -\x00\x00\x00\x18\ +\x00\x00\x00\x1a\ [\ -Controls]\x0aStyle=\ -Fusion\x0a\ +Controls]\x0d\x0aStyle\ +=Fusion\x0d\x0a\ \x00\x00\x01\x22\ <\ svg xmlns=\x22http:\ @@ -194,19 +194,19 @@ qt_resource_struct = b"\ \x00\x00\x000\x00\x02\x00\x00\x00\x06\x00\x00\x00\x03\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x01\x93*\xc9x\xac\ -\x00\x00\x00\x80\x00\x00\x00\x00\x00\x01\x00\x00\x02\x9f\ -\x00\x00\x01\x93*\xd6\x0c\xbc\ -\x00\x00\x00\x94\x00\x00\x00\x00\x00\x01\x00\x00\x03Y\ -\x00\x00\x01\x93*\xd6\x0c\xbd\ -\x00\x00\x00\xc4\x00\x00\x00\x00\x00\x01\x00\x00\x05\x9a\ -\x00\x00\x01\x93*\xd6\x0c\xbc\ -\x00\x00\x00\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x01B\ -\x00\x00\x01\x93*\xd6\x0c\xbc\ -\x00\x00\x00B\x00\x00\x00\x00\x00\x01\x00\x00\x00\x1c\ -\x00\x00\x01\x93*\xd6\x0c\xbd\ -\x00\x00\x00\xae\x00\x00\x00\x00\x00\x01\x00\x00\x04\xd5\ -\x00\x00\x01\x93*\xd6\x0c\xbd\ +\x00\x00\x01\x93)\xa6\xd7i\ +\x00\x00\x00\x80\x00\x00\x00\x00\x00\x01\x00\x00\x02\xa1\ +\x00\x00\x01\x93 \xd4\x11\xf3\ +\x00\x00\x00\x94\x00\x00\x00\x00\x00\x01\x00\x00\x03[\ +\x00\x00\x01\x93\x00\x9f\x10\x0d\ +\x00\x00\x00\xc4\x00\x00\x00\x00\x00\x01\x00\x00\x05\x9c\ +\x00\x00\x01\x93 \xd4\x11\xf4\ +\x00\x00\x00\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x01D\ +\x00\x00\x01\x93 \xd4\x11\xf4\ +\x00\x00\x00B\x00\x00\x00\x00\x00\x01\x00\x00\x00\x1e\ +\x00\x00\x01\x93\x00\xcf\xe6\x09\ +\x00\x00\x00\xae\x00\x00\x00\x00\x00\x01\x00\x00\x04\xd7\ +\x00\x00\x01\x92\xfc,B\x0e\ " def qInitResources(): diff --git a/rc_qml.py b/rc_qml.py index 8313f75..e32cb37 100644 --- a/rc_qml.py +++ b/rc_qml.py @@ -7,212 +7,222 @@ from PySide6 import QtCore qt_resource_data = b"\ \x00\x00\x01\xba\ -(\ -\xb5/\xfd`\xdd\x04\x85\x0d\x00\xb6\x13=\x1f0s\x1e\ -\xb3\xfb\x92H\xd4\xdc\x08\xd0\xcdc\xdb\xa9\xa2\xa0\xc4\xa4\ -\xbco\x17:w\xe6&\x14T4\x0c\x034\x003\x00\ -4\x00{5\x07\x9f\x8a\x9d\x83\xa1\xb9\x87UdHh\ -\xae\x9a\xf1\xedE}\x17W\x7fsTl\x0c\xc4:]\ -a\x8c~\xed\xcfF\xa8l\xff\xd9\x0c\x89i^\xac\x94\ -\xa7\xb4\xf7\xbe\xac\x18M(4A\x9b,]>\xbe(\ -/+\x10M\x90n#\x02\xb8\x85n\x9a{\x0fs\xf5\ -o\xeeWb(\xdf^@\xba\xd4\xec\xff\xba\x081\xf6\ -\x18\x96\xd4\x1b\xbe\xb9\xd2O\xf6\x8f}Z\xfe\xb4C\xe2\ -\xfc\x91'\xdf\x8f\xd6\xe45\x9c\x99\x9a\xb2\x9c\xd6\xe2l\ -\xf5\xd3\xca\x80L\xa6f\xd5\x84\x22im\xa4\x96h\xfc\ -\xbc6\x95\x9c\xa9\xed\xc8u9\x8a5\x8c\x19\x8c\x85\x10\ -\xcd\xcdX\xf9J\x1eV\xd1#\x8a\xdd[\xf6\x8b*\x0e\ -\x95\xeadk@\xb9Z+\x0e\xdc\xf3M\xd4\xdc\xecG\ -;\xb3/e\xc4Ho/\x0a-\xfe\x87\xa2\x9au\xc2\ -N\xa0\x91\x1dB\x8a!\x91))LZ\x03@\x84\x18\ -\xc6\xec\x1c\x03\x00\xb53i!-\xd8t\x01r\x1e\xc8\ -R\xc2\x99\x15\xe6\xba7\xf5\xb1\x85]\xd9d4\xe6\x0c\ -\x07\x95\x88^\xe0\xf7\x96\x0d\xeb\xc7\xa2\xaeQ\xbf\x96\xfd\ -\x93\x9c\xd3\x1cX\x94L7\x1bB\xb5\xb0\xc2tNJ\ -\x5c\xf0x\x18\x1d\xd3vQ\x82w\xa5\xf6\x18\xb9\xbb\xaa\ -\x8d)z\x08\x8f\xf5\xb8\x80\xe7*\xab\xbd\x0f\xd2\x92;\ -\xc4\xaa@\x8bdyf\xa1\x0d\xc2[\xc6\xa0QD\x18\ -\x97p\xb1\x85\xf3m3\x04\x05\x95=^\xd8SU\xe5\ -6\x9e\x93%!~\x0d`\x01_\xdb(\x5c\xa0\xa7\x82\ -\x03\xf0\xd6\xb8\x0d\x97\xd8n\x056\x87\xb4\xaf%\xb4\x0d\ -\x83\xfb\x1b\xe6\x8aD\x22w*\ -\x00\x00\x03,\ +\x00\ +\x00\x068x\xda\xb5TMo\xd40\x10\xbd\xaf\xb4\xff\ +\xc1\xca\x09\x84\x94\x16!\x0eD\xea\x81]8 Z\xa1\ +\xa2J\x9c\x1dg6q\xd7\xf1d\xc7cJ\x85\xfa\xdf\ +q\xe2m\x1c\xba(\x04\xa1\xfa\x10\xe5\xcd\xc7\xf3{c\ +it\xdb!\xb1\xb8\xe6k\xaf\xd5~\xbd\xd2\xbf\xe1|\ +\x8b\x96\x09\x8d;I\x5c\xca{\xf4\x1c\xe2\xeb\xd5W\xbc\ +\x8bh\xbd\xfa\xb9^\x89ptU\x08\xc6n#)b\ +\xd7I\xa5m]\x88\xf3\x88\x1b\xd0u\xc3\x85x\xf36\ +\xe2;]qS\x88N\x12X\xce\x07\x14\x13\xd2\xaa\x06\ +\xc9Ep$\xefO \x1f\xcb\xc3\x7fJ\x18\xd8\xf1\x98\ +\xe9A/0\xa6\x1f\x1e\x7f6\x9e\x19\xed\x09g/\xba\ +\x92\xae\xd9\xa0\xa4*\x85wF\x06F&\x0f\x93\xeb\xe1\ +G\x88\x1d\xdc\x0d\xbd\xc8>\x84\x96\xb2o\xc9^N\xb8\ +\xda\xceh\xa5\xf9[46\xd2\xe6\x8f\x89~\xaeA\xe2\ +\x90\x17\xaf\xc4\xeb\xf3\xd4\x8bv\x1bJ\xf6P\x15)6\ +\x919\x8c\xa5\xeb.QV@\xb9CO\x0a\xc4\x85H\ +:\xf2Ck\xb2T\xff\xf0/\xfe\xf7\xdeV`\x97\x9b\ +\xff<\xd4\xcf8\x8f\x84\xcfh{\xeb\x1dc\x0bt#\ +K\x03\xee\xd4\xfbR\xe7X\xde\xc2\x9e\x97;\xff2\xd4\ +\xcf8\x8f\x84s\xce\x97\x8bk5K*A3\xd0r\ +\x85W\xa9iF\xe6\x84\xfa\x19_\xe9c`\xc6{\xf8\ +\xdfG\x92%\x81j\xac\xb7\xf5\xf21\xbc\x1f{f\xa6\ +\x90\x88\xff6\x84Q\xe6'\x86\xf6\x8f\x22\x9b~\xdbM\ +\x1f*.\xc7|\xa7\x8d9^\x97\xd4.r\xcd\xf2\x16\ +\xdd$\xa6\xd0\x1eg[\x88\xec@\xaa8\xd3\xad\xac\xc1\ +\x9d\xb5`}\xee\xbe\xd7\xd9\x93b\x85\x06)\xd4\x12T\ +\xd9\xfc\xe4\x8eZ\xa9\xdf\xcfW\x92jm\x0b\xf1\xee\xc9\ +\x0e\x1d>\xbf\x00<\x0b\xa5\xbd\ +\x00\x00\x03Y\ i\ -mport QtQuick\x0aim\ -port QtQuick.Con\ -trols\x0aimport QtQ\ -uick.Layouts\x0a\x0aGr\ -idLayout\x0a{\x0a i\ -d: passEncryptKe\ -yGrid\x0a column\ -s: 2\x0a columnS\ -pacing: 5\x0a ro\ -wSpacing: 9\x0a \ -// anchors.fill:\ - parent\x0a\x0a pro\ -perty string nam\ -e: \x22pyqcrm\x22\x0a\x0a \ - Label\x0a {\x0a \ +mport QtQuick\x0d\x0ai\ +mport QtQuick.Co\ +ntrols\x0d\x0aimport Q\ +tQuick.Layouts\x0d\x0a\ +\x0d\x0aGridLayout\x0d\x0a{\x0d\ +\x0a id: passEnc\ +ryptKeyGrid\x0d\x0a \ + columns: 2\x0d\x0a \ + columnSpacing: \ +5\x0d\x0a rowSpacin\ +g: 9\x0d\x0a // anc\ +hors.fill: paren\ +t\x0d\x0a\x0d\x0a propert\ +y string name: \x22\ +pyqcrm\x22\x0d\x0a\x0d\x0a L\ +abel\x0d\x0a {\x0d\x0a \ text: qsTr(\ \x22Encryption Key \ -eingeben\x22)\x0a \ - font.pixelSiz\ -e: 40\x0a La\ -yout.columnSpan:\ - 2\x0a Layou\ -t.alignment: Qt.\ -AlignHCenter\x0a \ - padding: 15\ -\x0a }\x0a\x0a\x0a Lab\ -el\x0a {\x0a \ - text: qsTr(\x22Enc\ -ryption Key:\x22)\x0a \ +eingeben\x22)\x0d\x0a \ + font.pixelSi\ +ze: 40\x0d\x0a \ +Layout.columnSpa\ +n: 2\x0d\x0a La\ +yout.alignment: \ +Qt.AlignHCenter\x0d\ +\x0a padding\ +: 15\x0d\x0a }\x0d\x0a\x0d\x0a\x0d\ +\x0a Label\x0d\x0a \ +{\x0d\x0a text:\ + qsTr(\x22Encryptio\ +n Key:\x22)\x0d\x0a \ + Layout.alignme\ +nt: Qt.AlignRigh\ +t\x0d\x0a }\x0d\x0a\x0d\x0a \ +TextField\x0d\x0a {\ +\x0d\x0a id: pa\ +ssEncryptKey\x0d\x0a \ + placeholde\ +rText: qsTr(\x22Hie\ +r Encryption Key\ + eingeben\x22)\x0d\x0a \ + Layout.fill\ +Width: true\x0d\x0a \ + height: 3\x0d\x0a\ + echoMode\ +: TextInput.Pass\ +word\x0d\x0a pr\ +operty string na\ +me: \x22ENCRYPT_KEY\ +\x22\x0d\x0a }\x0d\x0a\x0d\x0a \ +Item\x0d\x0a {\x0d\x0a \ + Layout.fill\ +Height: true\x0d\x0a \ + }\x0d\x0a}\x0d\x0a\ +\x00\x00\x00#\ +m\ +odule gui\x0d\x0aTopBa\ +r 1.0 TopBar.qml\ +\x0d\x0a\ +\x00\x00\x02\x06\ +\x00\ +\x00\x07\xf8x\xda\xb5\x94Ms\xda0\x10\x86\xef\xcc\xf0\ +\x1f4>\xb5\x87\x924\xad3S\xe7\x04\x09\xad\x99\xc9\ +\x07`\x92\x1e;\xb2\xb5\x80&\xb2\xe4J\xeb\xe6k\xf8\ +\xef\x95b\x83\x9d\xba\x9d\x1a\x06l\x1f\xb4\xab\xd5\xee\xbb\ +\x8f%\xf14S\x1a\xc9\x04'9O\xee\xbb\x1d\xfe\xc6\ +\xee\x9d+\x89Z\x09\xd3\x98\xb8\xa4O*G\xebw\xef\ +7\xcdY\xe1\xe8v^\xba\x1db\x9f\xa3#\x92i\x95\ +\x81\xc6'B\x05\xa7\x86\xcc\xb96\x18!\xd5\x18\xd4\xc6\ +ni\xb1\x82\xb3\x80\xb0\xb8\xb2\x13%\xf2T\x9a\x80\x9c\ +\xd4\xed(\xa3\x09\x97\x8b\x80\xf8\x85W\xab\x87\x8d\xeb\x8b\ +\xd3\xe2\x9c\x9b\xca\x06\xb5\x9d!\x92\xa6\x10\x10\x8fQ\xa4\ +15\xe0\xad\xe3.i\x0c\xa2\x18\x96\xb2\xdd\x83\xf0h\ +%\xfe43\xfd\xce\xbb\xa0\x082\xa6\xf2\x9e\x0c\xb94\ +\x08B\xe4r\x01\xd2{_\x85\xcf-\xa2^\xc6\x1fA\ +D\xfc\xd9\x96\xf9|\x5c\xcd\x15Pz\x1b\xe9r\xd3M\ +m\xd6\xe2Y\xc8\x14\xa4-:\xc1^\xdfY\xe1\xb95\ +AW\xa1\x19e\xec\xb5\xc7\x8fe\xdf\xab\x82|\xcb.\ +\x06\x1fBe0\xa8\xcb\xfew\xf1)_,q\x9d|\ +\xb5\x1e\xccl\xbe\xaf\x1c\x04kT*~\x9c+P\xd3\ ++h\x02K%\x18\xe8YMH\xc8A\x13\x17I\xc0\ +v\x03\xf1[\x92\xa5\xa49\x17\xe2;g\xb8\x0c\x08\xea\ +\x1cjI\xff\xfe[/\x06?\xc2\x9bh\xe6\xfd!\xb8\ +\x15\x96\xb1\xdd\xd3\xdba\xd9\x0a\x8aK\xdf\x0eJ\xa9e\ +'.\xbf\xacZ\xbb\xb7\x95\x0e\xc8H\xe2\xdd\xdaz\x89\ +\x15\xa2J\xed\x9e9>\xf1\xcf\x08\xaa, \xa7\xbe\xff\ +\xc9?[\xb5a:\xbe\x99\xee\xc6\xf4\xda\xa58\x1cS\ +\x97\xbe5S\x17\xbc\xe7\xbdv\xdd\xbf\x1a\xee\xc4e\x00\ +2\xc7g\xd0\xf2\xb0|n\x0d\xe8\xad\x18\xd5u\xed\x99\ +\xd5m4\x9cz\x8d\xab\xa4\xdd\xc9\xa4\xc6<\x1c\xf8t\ +\x16%X\xe5\x87d\xa9\xae\x14\xb3\xea\xdd\xda\x91\xccl\ +\xb1f\xd4\xff\xceq\xa9|\xcf,\xc7\xfd(\xf2\x1a\x97\ +\xff\x08!m\xb4W+\x12\x82\x03S\xafb\x17\xdb\xef\ +7h\x023#\ +\x00\x00\x05\x86\ +i\ +mport QtQuick\x0d\x0ai\ +mport QtQuick.Co\ +ntrols\x0d\x0aimport Q\ +tQuick.Layouts\x0d\x0a\ +\x0d\x0aGridLayout\x0d\x0a{\x0d\ +\x0a id: createU\ +serGrid\x0d\x0a col\ +umns: 2\x0d\x0a col\ +umnSpacing: 5\x0d\x0a \ + rowSpacing: 9\ +\x0d\x0a // anchors\ +.fill: parent\x0d\x0a\x0d\ +\x0a property st\ +ring name: \x22user\ +\x22\x0d\x0a\x0d\x0a Label\x0d\x0a\ + {\x0d\x0a t\ +ext: qsTr(\x22Admin\ + User erstellen\x22\ +)\x0d\x0a font.\ +pixelSize: 40\x0d\x0a \ + Layout.co\ +lumnSpan: 2\x0d\x0a \ + Layout.alig\ +nment: Qt.AlignH\ +Center\x0d\x0a \ +padding: 15\x0d\x0a \ + }\x0d\x0a\x0d\x0a\x0d\x0a Labe\ +l\x0d\x0a {\x0d\x0a \ + text: qsTr(\x22Be\ +nutzername:\x22)\x0d\x0a \ Layout.al\ ignment: Qt.Alig\ -nRight\x0a }\x0a\x0a \ - TextField\x0a \ -{\x0a id: pa\ -ssEncryptKey\x0a \ - placeholder\ -Text: qsTr(\x22Hier\ - Encryption Key \ -eingeben\x22)\x0a \ - Layout.fillWi\ -dth: true\x0a \ - height: 3\x0a \ - echoMode: Te\ -xtInput.Password\ +nRight\x0d\x0a }\x0d\x0a\x0d\ +\x0a TextField\x0d\x0a\ + {\x0d\x0a i\ +d: benutzerName\x0d\ +\x0a placeho\ +lderText: qsTr(\x22\ +Hier Benutzernam\ +e eingeben\x22)\x0d\x0a \ + Layout.fil\ +lWidth: true\x0d\x0a \ + height: 3\x0d\ \x0a propert\ y string name: \x22\ -ENCRYPT_KEY\x22\x0a \ - }\x0a\x0a Item\x0a \ - {\x0a Layou\ -t.fillHeight: tr\ -ue\x0a }\x0a}\x0a\ -\x00\x00\x00!\ -m\ -odule gui\x0aTopBar\ - 1.0 TopBar.qml\x0a\ -\ -\x00\x00\x01\xd2\ -(\ -\xb5/\xfd`T\x06E\x0e\x006VE \x95\x1b\ -:\xbd\x94\x0a\x13I\xcc\x02\xb9\x88y\xd8\x9e\x053\x99\ -t\x01\xbd\x03\x9c\xf1\x18q\x02\xa4`\xa0 :\x00:\ -\x00;\x00\x0c\xafo\x1d\xad\x19&\x19\xca\x09\xdf\xc6\xb7\ -\xfe\xda\xc9\xe1\x1b'\x8d,z\xdb\x5c\xb5\x1c\x0f\x06\xcc\ -\xcc\x8f\xf4\xe4\xb4\x90\xf7\xde\xfd\xae\x8a\xa2\xe4\xd2j\xdf\ -+\x83z\x9elv\x97\xbf\xf0\xdb\xcam3\x16\xed\xd0\ -\xe4\xa8\xf7\xca\x09L\xde\x9aw\x94\xf6_\x9f\x0e\xf6x\ -\xc4\xbc?6&\x80\xbd\xee\x87\xe1\x87\xfaicQ2\ -\xf5\x8dX\xfc('\x86\xbdEg\xfb\xf7%@\xd5\x22\ -\x18j>\xb3\xc8Y\x86\x8d\xb5\xe6\xb3\x99m\xcf\xea\xb2\ --i\xedt\x16\xa9\xa4=\x1f\x1f\xea\xeb}G\x9b\x98\ -\xc0\x04\xff\xd6J\xb0x\xa5\x82\x94\x91\xb3\xfd\xde\x8cJ\ -A\xfd\x85\xe1{o\xaeM\x1a\x0d\x0c\x9d\x22\x1c\x18\xf6\ -h\x06\xaf\xd4\xd5\xd6\x1f\xb1,\x05\xf5\x1d\xe7\x11\xd8\xb2\ -Nj'k\x09\xba7\xbe\x09\xe3\xb02\xb6o\xc6m\ -\x8f\xbe\xf3^8&\x0aJo\x91\x82\xa9Xl\xb5L\ -\x97U\xa96\x8bFw\xf6\x19v^N\x0d\xa5\x93\xe3\ -\x01J\xa0\x91\x11R\xce\x94\x88\x8d\x92(\x9b\x01p&\ -\x10\xab2\x0fZ\x99\xb8\xb1\x06\x06\x843+\xcd\x06\x5c\ -\xd3g\x83\xcec\x18b!$5\xb7q\xa5\x06\xd6A\ -\xa63M\x97\xcdDuH\x11\x0a\xb4\x94Q\xf3\xaa\xa2\ -\xc9bD\x0b\x11V?\x8e\x00\xc2\xe9l\xd46\x80\x22\ -\x8e\xd1\x9f\x9b\xe0A\x97\xcd\x17\xfa6\x16\x8a\x84;\xc4\ -\x84t\xc8#\x8b\x1d\x096\x95\xb2\xbb\xda\xa2*\xde,\ -\xbe\xc6\x8e\x1c\x08N2\xfcP(\x1c\x88.\x9a\xd8V\ -\x1d\xb5\x06\x82l\xcd\x85\x82\x86\xc6W~\xe3\xe5\x02X\ -\x9c[\xdcq\xca@{\xf0f\xady\xa9Z\x15\xbf\x87\ -\xe6\xe4\x05\xfd\xe5\xc2Z\x1e\xa6\x8a\x0f\xb8\x22!r\xf7\ -\x03\ -\x00\x00\x05C\ -i\ -mport QtQuick\x0aim\ -port QtQuick.Con\ -trols\x0aimport QtQ\ -uick.Layouts\x0a\x0aGr\ -idLayout\x0a{\x0a i\ -d: createUserGri\ -d\x0a columns: 2\ -\x0a columnSpaci\ -ng: 5\x0a rowSpa\ -cing: 9\x0a // a\ -nchors.fill: par\ -ent\x0a\x0a propert\ -y string name: \x22\ -pyqcrm\x22\x0a\x0a Lab\ -el\x0a {\x0a \ - text: qsTr(\x22Adm\ -in User erstelle\ -n\x22)\x0a font\ -.pixelSize: 40\x0a \ - Layout.co\ -lumnSpan: 2\x0a \ - Layout.align\ -ment: Qt.AlignHC\ -enter\x0a pa\ -dding: 15\x0a }\x0a\ -\x0a\x0a Label\x0a \ -{\x0a text: \ -qsTr(\x22Benutzerna\ -me:\x22)\x0a La\ -yout.alignment: \ -Qt.AlignRight\x0a \ - }\x0a\x0a TextFie\ -ld\x0a {\x0a \ - id: benutzerNam\ -e\x0a placeh\ -olderText: qsTr(\ -\x22Hier Benutzerna\ -me eingeben\x22)\x0a \ - Layout.fil\ -lWidth: true\x0a \ - height: 3\x0a \ - property \ -string name: \x22PY\ -QCRM_ADMIN\x22\x0a \ -}\x0a\x0a Label\x0a \ - {\x0a text:\ - qsTr(\x22Passwort:\ -\x22)\x0a Layou\ -t.alignment: Qt.\ -AlignRight\x0a }\ -\x0a\x0a TextField\x0a\ - {\x0a id\ -: password\x0a \ - echoMode: Tex\ -tInput.Password\x0a\ - placehol\ -derText: qsTr(\x22H\ -ier Passwort ein\ -geben\x22)\x0a \ -Layout.fillWidth\ -: true\x0a p\ +PYQCRM_USER\x22\x0d\x0a \ + }\x0d\x0a\x0d\x0a Label\ +\x0d\x0a {\x0d\x0a \ + text: qsTr(\x22Pas\ +swort:\x22)\x0d\x0a \ + Layout.alignme\ +nt: Qt.AlignRigh\ +t\x0d\x0a }\x0d\x0a\x0d\x0a \ +TextField\x0d\x0a {\ +\x0d\x0a id: pa\ +ssword\x0d\x0a \ +echoMode: TextIn\ +put.Password\x0d\x0a \ + placeholde\ +rText: qsTr(\x22Hie\ +r Passwort einge\ +ben\x22)\x0d\x0a L\ +ayout.fillWidth:\ + true\x0d\x0a p\ roperty string n\ -ame: \x22PYQCRM_ADM\ -IN_PASS\x22\x0a }\x0a \ - Label\x0a {\x0a \ - text: qsT\ -r(\x22Info:\x22)\x0a \ - Layout.alignm\ -ent: Qt.AlignRig\ -ht\x0a }\x0a\x0a Te\ -xtField\x0a {\x0a \ - id: gecos\x0a\ - placehol\ -derText: qsTr(\x22Z\ -us\xc3\xa4tzliche Info\ -\x22)\x0a Layou\ -t.fillWidth: tru\ -e\x0a proper\ -ty string name: \ -\x22PYQCRM_ADMIN_IN\ -FO\x22\x0a }\x0a\x0a I\ -tem\x0a {\x0a \ +ame: \x22PYQCRM_USE\ +R_PASS\x22\x0d\x0a }\x0d\x0a\ + Label\x0d\x0a {\ +\x0d\x0a text: \ +qsTr(\x22Info:\x22)\x0d\x0a \ + Layout.al\ +ignment: Qt.Alig\ +nRight\x0d\x0a }\x0d\x0a\x0d\ +\x0a TextField\x0d\x0a\ + {\x0d\x0a i\ +d: gecos\x0d\x0a \ + placeholderTex\ +t: qsTr(\x22Zus\xc3\xa4tz\ +liche Info\x22)\x0d\x0a \ + Layout.fil\ +lWidth: true\x0d\x0a \ + property s\ +tring name: \x22PYQ\ +CRM_USER_INFO\x22\x0d\x0a\ + }\x0d\x0a\x0d\x0a Ite\ +m\x0d\x0a {\x0d\x0a \ Layout.fillHei\ -ght: true\x0a }\x0a\ -}\x0a\ +ght: true\x0d\x0a }\ +\x0d\x0a}\x0d\x0a\ " qt_resource_name = b"\ @@ -251,15 +261,15 @@ qt_resource_struct = b"\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x02\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00&\x00\x00\x00\x00\x00\x01\x00\x00\x01\xbe\ -\x00\x00\x01\x93c~Y\x0a\ -\x00\x00\x00\x8c\x00\x00\x00\x00\x00\x01\x00\x00\x06\xe9\ -\x00\x00\x01\x93cIV\x9c\ -\x00\x00\x00N\x00\x00\x00\x00\x00\x01\x00\x00\x04\xee\ -\x00\x00\x01\x930& \x0f\ -\x00\x00\x00\x0c\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x01\x93*\xc9x\xab\ -\x00\x00\x00`\x00\x04\x00\x00\x00\x01\x00\x00\x05\x13\ -\x00\x00\x01\x93cI\x95\xbf\ +\x00\x00\x01\x93q\xc1B\xf5\ +\x00\x00\x00\x8c\x00\x00\x00\x00\x00\x01\x00\x00\x07L\ +\x00\x00\x01\x93q\xc1B\xf3\ +\x00\x00\x00N\x00\x00\x00\x00\x00\x01\x00\x00\x05\x1b\ +\x00\x00\x01\x93>1\xe8\xfe\ +\x00\x00\x00\x0c\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01\x93>1\xe8\xfc\ +\x00\x00\x00`\x00\x01\x00\x00\x00\x01\x00\x00\x05B\ +\x00\x00\x01\x93q\xc1B\xf4\ " def qInitResources():