Login, user in datenbank und encryption key

This commit is contained in:
2024-12-02 16:15:26 +01:00
parent 70ad4d557b
commit 5bf35ce12a
9 changed files with 309 additions and 309 deletions

View File

@@ -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
}
}

View File

@@ -37,6 +37,7 @@ RowLayout
implicitWidth: kunden.implicitContentWidth + 10
onClicked:
{
// TODO: here we should call the model
appLoader.source = "CustomerTables.qml"
}
}

View File

@@ -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)
}
}

View File

@@ -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)
@Slot(str)
def setEncyrptKey(self, key):
self.__config['pyqcrm']['ENCRYPTION_KEY'] = key
print(self.__config)
self.__saveConfig()
def __saveConfig(self):

View File

@@ -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.__hashPassword()
user_created = True
try:
self.__cur.callproc("createUser", (self.__username, self.__password, self.__info, self.__role))
self.__con.commit()
self.__closeConnection()
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()

View File

@@ -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

View File

@@ -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()

View File

@@ -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():

422
rc_qml.py
View File

@@ -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():