diff options
| author | Debulois <quentin@debulois.fr> | 2022-04-15 16:09:55 +0200 |
|---|---|---|
| committer | Debulois <quentin@debulois.fr> | 2022-04-15 16:09:55 +0200 |
| commit | 5ca5b78cef1359ca29295992c61042d6ea5375d2 (patch) | |
| tree | dbfdbb73aa87e3dba9a9ba2f4b024e69cb9eede9 | |
Initial commit, traduction des fichiers databases de PHP et système de vérification des mots de passe sur la bdd en local
| -rw-r--r-- | app_alphajob/database/__init__.py | 1 | ||||
| -rw-r--r-- | app_alphajob/database/__pycache__/__init__.cpython-310.pyc | bin | 0 -> 164 bytes | |||
| -rw-r--r-- | app_alphajob/database/__pycache__/dbmain.cpython-310.pyc | bin | 0 -> 6816 bytes | |||
| -rw-r--r-- | app_alphajob/database/__pycache__/dbsearch.cpython-310.pyc | bin | 0 -> 3661 bytes | |||
| -rw-r--r-- | app_alphajob/database/__pycache__/dbuser.cpython-310.pyc | bin | 0 -> 3674 bytes | |||
| -rw-r--r-- | app_alphajob/database/dbadmin.py | 177 | ||||
| -rw-r--r-- | app_alphajob/database/dbmain.py | 217 | ||||
| -rw-r--r-- | app_alphajob/database/dbmission.py | 160 | ||||
| -rw-r--r-- | app_alphajob/database/dbsearch.py | 140 | ||||
| -rw-r--r-- | app_alphajob/database/dbuser.py | 171 | ||||
| -rw-r--r-- | app_alphajob/main.py | 119 | ||||
| -rw-r--r-- | app_alphajob/ressources/icon.ico | bin | 0 -> 41662 bytes | |||
| -rw-r--r-- | requierments.txt | bin | 0 -> 342 bytes |
13 files changed, 985 insertions, 0 deletions
diff --git a/app_alphajob/database/__init__.py b/app_alphajob/database/__init__.py new file mode 100644 index 0000000..03b0cc7 --- /dev/null +++ b/app_alphajob/database/__init__.py @@ -0,0 +1 @@ +# https://realpython.com/python-import/#basic-python-import
\ No newline at end of file diff --git a/app_alphajob/database/__pycache__/__init__.cpython-310.pyc b/app_alphajob/database/__pycache__/__init__.cpython-310.pyc Binary files differnew file mode 100644 index 0000000..d1a6aa3 --- /dev/null +++ b/app_alphajob/database/__pycache__/__init__.cpython-310.pyc diff --git a/app_alphajob/database/__pycache__/dbmain.cpython-310.pyc b/app_alphajob/database/__pycache__/dbmain.cpython-310.pyc Binary files differnew file mode 100644 index 0000000..91f77db --- /dev/null +++ b/app_alphajob/database/__pycache__/dbmain.cpython-310.pyc diff --git a/app_alphajob/database/__pycache__/dbsearch.cpython-310.pyc b/app_alphajob/database/__pycache__/dbsearch.cpython-310.pyc Binary files differnew file mode 100644 index 0000000..48e2dc6 --- /dev/null +++ b/app_alphajob/database/__pycache__/dbsearch.cpython-310.pyc diff --git a/app_alphajob/database/__pycache__/dbuser.cpython-310.pyc b/app_alphajob/database/__pycache__/dbuser.cpython-310.pyc Binary files differnew file mode 100644 index 0000000..7442540 --- /dev/null +++ b/app_alphajob/database/__pycache__/dbuser.cpython-310.pyc diff --git a/app_alphajob/database/dbadmin.py b/app_alphajob/database/dbadmin.py new file mode 100644 index 0000000..dd6b4d0 --- /dev/null +++ b/app_alphajob/database/dbadmin.py @@ -0,0 +1,177 @@ + +############################################################################ +# # +# Description: Ensemble de méthodes pour étendre dbmain # +# afin de gérer l'administration du site # +# # +############################################################################ + +# Import de dbmain +from . import dbmain + +# Extension de cette classe avec dbmain +class DbAdmin(dbmain.DbMain): + + # **************************************************************************** + # GESTION DES UTILISATEURS DANS L'ADMIN + # **************************************************************************** + # Récupérer toutes les infos de la table userAccount + def get_all_users_account(self): + reqGetAll = """ + SELECT + * + FROM + """ + self.TABLEUSERACCOUNT + # https:#www.php.net/manual/fr/pdostatement.fetch.php + # "PDO::FETCH_ASSOC: retourne un tableau indexé + # par le nom de la colonne comme retourné dans le jeu de résultats" + self.exec_cmd(reqGetAll) + result = self.cur.fetchall() + return result + + # https:#stackoverflow.com/questions/1361340/how-can-i-do-insert-if-not-exists-in-mysql + # Suppresion d'un utilisateur + def del_user_by_userid(self, userId): + # Préparation de la requète pour voir si l'utilisateur existe + # https:#stackoverflow.com/questions/1676551/best-way-to-test-if-a-row-exists-in-a-mysql-table + reqCheckExistId = """ + SELECT EXISTS( + SELECT 1 FROM + """ + self.TABLEUSERACCOUNT + """ + WHERE + userId = ? + LIMIT 1 + )""" + # Exécution de la requète, fetchall pour avoir le résultat + # https:#www.php.net/manual/fr/pdostatement.fetch.php + # struct par défaut req et index (fetch_both) = arr([0] => arr("req" => BOOL, [0] => BOOL]) + # PDO::FETCH_NUM : retourne un tableau indexé par le numéro de la colonne comme elle + # est retourné dans votre jeu de résultat, commençant à 0 + self.exec_cmd(reqCheckExistId, [userId]) + reqResult = self.cur.fetchall() + # Si il existe + if (reqResult[0][0]): + # Préparation de la requète pour suppression + reqDelUser = """DELETE FROM """ + self.TABLEUSERACCOUNT + """ WHERE userId = ?""" + # Exécution de la requète + self.exec_cmd(reqDelUser, [userId]) + # Retourne 1 pour réussite + return 1 + else: + # Retourne 0 pour échec + return 0 + + + # **************************************************************************** + # GESTION DES EMPLOIS DANS L'ADMIN + # **************************************************************************** + # Ajout d'une categorie + def register_job_category(self, jobNameEn, jobNameFr): + # Préparation et execution de la requète pour voir si la categorie existe en anglais + reqCheckjobCategoryNameEn = """ + SELECT EXISTS( + SELECT 1 FROM + """ + self.TABLEJOBCATEGORY + """ + WHERE + jobCategoryNameEn = ? + LIMIT 1 + )""" + self.exec_cmd(reqCheckjobCategoryNameEn, [jobNameEn]) + reqResultEn = self.cur.fetchall() + # Si il n'existe pas en anglais + if not reqResultEn[0][0]: + # Préparation et execution de la requète pour voir si la categorie existe en Français + reqCheckjobCategoryNameFr = """ + SELECT EXISTS( + SELECT 1 FROM + """ + self.TABLEJOBCATEGORY + """ + WHERE + jobCategoryNameFr = ? + LIMIT 1 + )""" + self.exec_cmd(reqCheckjobCategoryNameFr, [jobNameFr]) + reqResultFr = self.cur.fetchall() + # Si il n'existe pas en Français non plus + if not reqResultFr[0][0]: + # Préparation de la requète pour l'ajout + reqjobCategoryNameAdd = """ + INSERT INTO + """ + self.TABLEJOBCATEGORY + """ + (jobCategoryNameEn, jobCategoryNameFr) + VALUES + (? ,?)""" + # Exécution de la requète + self.exec_cmd(reqjobCategoryNameAdd, [jobNameEn, jobNameFr]) + # Retourne 1 pour réussite + return 1 + else: + # Retourne 0 pour échec + return 0 + else: + # Retourne 0 pour échec + return 0 + + # Suppresion d'un utilisateur + def del_job_category_by_jobid(self, jobId): + # Préparation de la requète pour voir si l'utilisateur existe + reqCheckExistId = """ + SELECT EXISTS( + SELECT 1 FROM + """ + self.TABLEJOBCATEGORY + """ + WHERE + jobCategoryId = ? + LIMIT 1 + )""" + # Exécution de la requète, fetchall pour avoir le résultat + # struct par défaut req et index (fetch_both) = arr([0] => arr("req" => BOOL, [0] => BOOL]) + # fetch_num pour casser l'index "req" en chiffre, dict -> list + self.exec_cmd(reqCheckExistId, [jobId]) + reqResult = self.cur.fetchall() + # Si il existe + if (reqResult[0][0]): + # Préparation de la requète pour suppression + reqDelJobCategory = """ + DELETE FROM + """ + self.TABLEJOBCATEGORY + """ + WHERE + jobCategoryId = ?""" + # Exécution de la requète + self.exec_cmd(reqDelJobCategory, [jobId]) + # Retourne 1 pour réussite + return 1 + else: + # Retourne 0 pour échec + return 0 + + # **************************************************************************** + # GESTION DES MISSIONS DANS L'ADMIN + # **************************************************************************** + # Suppresion d'une mission + def del_mission_by_missionid(self, missionId): + # Préparation de la requète pour voir si l'utilisateur existe + reqCheckExistId = """ + SELECT EXISTS( + SELECT 1 FROM + """ + self.TABLEMISSION + """ + WHERE + missionId = ? + LIMIT 1 + )""" + # Exécution de la requète + self.exec_cmd(reqCheckExistId, [missionId]) + reqResult = self.cur.fetchall() + # Si il existe + if (reqResult[0][0]): + # Préparation de la requète pour suppression + reqDelMission = """ + DELETE FROM + """ + self.TABLEMISSION + """ + WHERE + missionId = ?""" + # Exécution de la requète + self.exec_cmd(reqDelMission, [missionId]) + # Retourne 1 pour réussite + return 1 + else: + # Retourne 0 pour échec + return 0 diff --git a/app_alphajob/database/dbmain.py b/app_alphajob/database/dbmain.py new file mode 100644 index 0000000..602cec6 --- /dev/null +++ b/app_alphajob/database/dbmain.py @@ -0,0 +1,217 @@ + +############################################################################ +# # +# Description: Partie commune des deux ensembles de méthodes # +# pour la gestion de la BDD # +# # +############################################################################ + +import mysql.connector +from passlib.hash import sha512_crypt + +# const si CAPS +# https://www.w3schools.com/python/python_mysql_getstarted.asp +# https://dev.mysql.com/doc/connector-python/en/connector-python-connectargs.html +# https://stackoverflow.com/questions/11565487/python-equivalent-of-php-mysql-fetch-array + + +class DbMain(): + # **************************************************************************** + # INFOS GLOBAL ET DE CONNEXION + # **************************************************************************** + # Pour gérer si "en production" + DEBUG = False + # Configuration du serveur MYSQL / MARIADB + HOST = "127.0.0.1" + USER = "root" + PASSWORD = "" + DATABASE = "alphajob" + + # **************************************************************************** + # DECLARATION DES TABLES + # **************************************************************************** + # UserAccount, infos du compte nécessaire à la connection + CREATETABLEUSERACCOUNT = """CREATE TABLE IF NOT EXISTS `alphajob`.`userAccount` ( + `userId` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `email` VARCHAR(128) NOT NULL, + `password` VARCHAR(128) NOT NULL, + `tokenAutoLogin` VARCHAR(128) NULL DEFAULT NULL, + `inscriptionDate` TIMESTAMP NOT NULL, + `userStatus` TINYINT(1) UNSIGNED NOT NULL, + PRIMARY KEY (`userId`) + ) + ENGINE = InnoDB + DEFAULT CHARACTER SET = utf8;""" + + # Infos complémentaires des utilisateur, liée à userAccount par userId + CREATETABLEUSERINFO = """CREATE TABLE IF NOT EXISTS `alphajob`.`userInfo` ( + `lastname` VARCHAR(128) NOT NULL, + `firstname` VARCHAR(128) NOT NULL, + `phoneNumber` VARCHAR(10) NOT NULL, + `adress` VARCHAR(128) NOT NULL, + `zipCode` VARCHAR(6) NOT NULL, + `city` VARCHAR(128) NOT NULL, + `degree` VARCHAR(128) NULL DEFAULT NULL, + `capability` VARCHAR(256) NULL DEFAULT NULL, + `description` VARCHAR(256) NULL DEFAULT NULL, + `userId` INT UNSIGNED NOT NULL, + PRIMARY KEY (`userId`), + INDEX `fk_userinfo_userId_idx` (`userId` ASC) VISIBLE, + CONSTRAINT `fk_userinfo_userId` + FOREIGN KEY (`userId`) + REFERENCES `alphajob`.`userAccount` (`userId`) + ON DELETE CASCADE + ON UPDATE CASCADE + ) + ENGINE = InnoDB + DEFAULT CHARACTER SET = utf8;""" + + # Liste des categories d'emploie possible + CREATETABLEJOBCATEGORY = """CREATE TABLE IF NOT EXISTS `alphajob`.`jobCategory` ( + `jobCategoryId` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `jobCategoryNameEn` VARCHAR(128) NOT NULL, + `jobCategoryNameFr` VARCHAR(128) NOT NULL, + PRIMARY KEY (`jobCategoryId`) + ) + ENGINE = InnoDB + DEFAULT CHARACTER SET = utf8;""" + + # Assosications des emploies à un utilisateur + CREATETABLEUSERJOB = """CREATE TABLE IF NOT EXISTS `alphajob`.`userJob` ( + `userId` INT UNSIGNED NOT NULL, + `jobCategoryId` INT UNSIGNED NOT NULL, + INDEX `fk_userInfo_userId_idx` (`userId` ASC) VISIBLE, + INDEX `fk_jobCategory_jobCategoryId_idx` (`jobCategoryId` ASC) VISIBLE, + CONSTRAINT `fk_userJob_userId` + FOREIGN KEY (`userId`) + REFERENCES `alphajob`.`userAccount` (`userId`) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT `fk_userJob_jobCategoryId` + FOREIGN KEY (`jobCategoryId`) + REFERENCES `alphajob`.`jobCategory` (`jobCategoryId`) + ON DELETE CASCADE + ON UPDATE CASCADE + ) + ENGINE = InnoDB + DEFAULT CHARACTER SET = utf8;""" + + # Infos sur les missions effectuées, liée à userAccount par userId et consultantId + CREATETABLEMISSION = """CREATE TABLE IF NOT EXISTS `alphajob`.`mission` ( + `missionId` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `date` TIMESTAMP NOT NULL, + `subject` VARCHAR(128) NULL DEFAULT NULL, + `note` TINYINT(1) UNSIGNED NULL DEFAULT NULL, + `review` VARCHAR(256) NULL DEFAULT NULL, + `acceptedByPro` TIMESTAMP NULL DEFAULT NULL, + `validatedByClient` TIMESTAMP NULL DEFAULT NULL, + `validatedByPro` TIMESTAMP NULL DEFAULT NULL, + `clientId` INT UNSIGNED NOT NULL, + `proId` INT UNSIGNED NOT NULL, + `jobCategoryId` INT UNSIGNED NOT NULL, + PRIMARY KEY (`missionId`), + INDEX `fk_mission_clientId_idx` (`clientId` ASC) VISIBLE, + INDEX `fk_mission_proId_idx` (`proId` ASC) VISIBLE, + INDEX `fk_mission_jobCategoryId_idx` (`jobCategoryId` ASC) VISIBLE, + CONSTRAINT `fk_mission_clientId` + FOREIGN KEY (`clientId`) + REFERENCES `alphajob`.`userAccount` (`userId`) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT `fk_mission_proId` + FOREIGN KEY (`proId`) + REFERENCES `alphajob`.`userAccount` (`userId`) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT `fk_mission_jobCategoryId` + FOREIGN KEY (`jobCategoryId`) + REFERENCES `alphajob`.`jobCategory` (`jobCategoryId`) + ON DELETE CASCADE + ON UPDATE CASCADE + ) + ENGINE = InnoDB + DEFAULT CHARACTER SET = utf8""" + + # Noms des tables + TABLEUSERACCOUNT = "userAccount" + TABLEUSERINFO = "userInfo" + TABLEJOBCATEGORY = "jobCategory" + TABLEUSERJOB = "userJob" + TABLEMISSION = "mission" + + # **************************************************************************** + # FONCTIONS PRINCIPALES + # **************************************************************************** + # Constructeur, fonction "auto" déclenchée à l'instanciation + def __init__(self): + if self.DEBUG: + self.conn = mysql.connector.connect( + host=self.HOST, + user=self.USER, + password=self.PASSWORD, + database=self.DATABASE, + raise_on_warnings=self.DEBUG + ) + else: + self.conn = mysql.connector.connect( + host=self.HOST, + user=self.USER, + password=self.PASSWORD, + database=self.DATABASE + ) + self.cur = self.conn.cursor() + + # Création de la DB si elle n'existe pas + def create_db(self): + reqInitDb = "CREATE DATABASE IF NOT EXISTS " + self.DATABASE + self.cur.execute(reqInitDb) + + # Sélection de la DB + def select_db(self): + reqSelectDb = "USE " + self.DATABASE + self.cur.execute(reqSelectDb) + + # Création des tables si elles n'existent pas + def create_table(self): + # userAccount + reqInitUserAccount = self.CREATETABLEUSERACCOUNT + self.cur.execute(reqInitUserAccount) + # userInfo + reqInitUserInfo = self.CREATETABLEUSERINFO + self.cur.execute(reqInitUserAccount) + # jobCategory + reqInitJobCategory = self.CREATETABLEJOBCATEGORY + self.cur.execute(reqInitJobCategory) + # userJob + reqInitUserJob = self.CREATETABLEUSERJOB + self.cur.execute(reqInitUserJob) + # mission + reqInitMission = self.CREATETABLEMISSION + self.cur.execute(reqInitMission) + + # Déclenche les méthodes pour créer la BDD + def init(self): + self.create_db() + self.select_db() + self.create_table() + + # Chiffre la data reçue + def crypt_pass(self, password): + return sha512_crypt.hash(password, rounds=10000) + + # Prépare la requète pour mitiger (se protéger) les injections SQL et + # initialise si nécessaire la BDD à chaque requète + def exec_cmd(self, req, arg=None): + self.init() + if arg: + self.cur.execute(req, arg) + else: + self.cur.execute(req) + + # Vérifie si l'email existe dans la table userAccount de la BDD + def check_exist_email(self, email): + reqCheckEmailExist = "SELECT EXISTS(SELECT * FROM " + \ + self.TABLEUSERACCOUNT + " WHERE email = %s)" + self.exec_cmd(reqCheckEmailExist, [email]) + # Retourne 1 si existe, sinon 0 + return self.cur.fetchall()[0][0] diff --git a/app_alphajob/database/dbmission.py b/app_alphajob/database/dbmission.py new file mode 100644 index 0000000..0a33a12 --- /dev/null +++ b/app_alphajob/database/dbmission.py @@ -0,0 +1,160 @@ + +# ############################################################################ +# # # +# # Description: Ensemble de méthodes pour étendre dbmain afin # +# # d'effectuer des recherches dans la bdd # +# # # +# ############################################################################ + +# Infos pour les "join": +# https:#www.freecodecamp.org/news/sql-joins-tutorial/ + +# Import de dbmain +from . import dbmain +from datetime import datetime + + +# Extension de cette classe avec dbmain +class DbMission(dbmain.DbMain): + + # **************************************************************************** + # ENREGISTREMENT ET VALIDATION DES MISSIONS + # **************************************************************************** + # Enregistrement d'une mission + def register_mission(self, subject, clientId, proId, jobId): + # Préparation de la requète pour enregistrement de la mission + reqAddMission = """ + INSERT INTO """ + self.TABLEMISSION + """ + (date, subject, clientId, proId, jobCategoryId) + VALUES + (?, ?, ?, ?, ?)""" + # Exécution de la requète + self.exec_cmd(reqAddMission, + [datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + subject, + clientId, + proId, + jobId + ] + ) + return 1 + + # Enregistrement d'une mission + def accept_mission_by_missionid(self, missionId): + # Préparation de la requète pour enregistrement de la mission + reqAddMission = """ + UPDATE + """ + self.TABLEMISSION + """ + SET + acceptedByPro = ? + WHERE + missionId = ?""" + # Exécution de la requète + self.exec_cmd(reqAddMission, [datetime.now().strftime("%Y-%m-%d %H:%M:%S"), missionId]) + return 1 + + def validate_mission_pro_by_missionid(self, missionId): + # Préparation de la requète pour enregistrement de la mission + reqAddMission = """ + UPDATE + """ + self.TABLEMISSION + """ + SET + validatedByPro = ? + WHERE + missionId = ?""" + # Exécution de la requète + self.exec_cmd(reqAddMission, [datetime.now().strftime("%Y-%m-%d %H:%M:%S"), missionId]) + return 1 + + def validate_mission_client_by_missionid(self, missionId): + # Préparation de la requète pour enregistrement de la mission + reqAddMission = """ + UPDATE + """ + self.TABLEMISSION + """ + SET + validatedByClient = ? + WHERE + missionId = ?""" + # Exécution de la requète + self.exec_cmd(reqAddMission, [datetime.now().strftime("%Y-%m-%d %H:%M:%S"), missionId]) + return 1 + + def review_mission(self, missionId, review, note): + # Préparation de la requète pour enregistrement de la mission + reqAddMission = """ + UPDATE + """ + self.TABLEMISSION + """ + SET + review = ?, note = ? + WHERE + missionId = ?""" + # Exécution de la requète + self.exec_cmd(reqAddMission, [review, note, missionId]) + return 1 + + # **************************************************************************** + # RECUPERATION DES INFORMATIONS RELATIVES AUX MISSIONS + # **************************************************************************** + # Récupérations des missions d'un pro par son id + def get_mission_by_proid(self, proId): + reqGetMissionsProId = """ + SELECT + missionId, date, subject, note, review, + acceptedByPro, validatedByClient, + validatedByPro, jobCategoryId, proId, lastname + FROM + """ + self.TABLEMISSION + """ + LEFT JOIN + """ + self.TABLEUSERINFO + """ + ON + """ + self.TABLEMISSION + """.proId = """ + self.TABLEUSERINFO + """.userId + WHERE + proId = ?""" + self.exec_cmd(reqGetMissionsProId, [proId]) + result = self.cur.fetchall() + return result + + # Récupérations des missions d'un client par son id + def get_mission_by_clientid(self, clientId): + reqGetMissionsClientId = """ + SELECT + missionId, date, subject, note, review, + acceptedByPro, validatedByClient, + validatedByPro, jobCategoryId, proId, lastname + FROM + """ + self.TABLEMISSION + """ + LEFT JOIN + """ + self.TABLEUSERINFO + """ + ON + """ + self.TABLEMISSION + """.proId = """ + self.TABLEUSERINFO + """.userId + WHERE + clientId = ?""" + self.exec_cmd(reqGetMissionsClientId, [clientId]) + result = self.cur.fetchall() + return result + + # Récupérations des missions d'un client par son id + def get_all_missions(self): + reqGetAllMission = """ + SELECT + * + FROM + """ + self.TABLEMISSION + self.exec_cmd(reqGetAllMission) + result = self.cur.fetchall() + return result + + # Compte le nombre de mission d'un consultant par son nom + def count_pro_missions_by_proid(self, proId): + reqCountMission = """ + SELECT COUNT(*) FROM + """ + self.TABLEMISSION + """ + INNER JOIN + """ + self.TABLEUSERINFO + """ + ON + """ + self.TABLEMISSION + """.proId = """ + self.TABLEUSERINFO + """.userId + WHERE + proId = ?""" + self.exec_cmd(reqCountMission, [proId]) + result = self.cur.fetchall() + return result diff --git a/app_alphajob/database/dbsearch.py b/app_alphajob/database/dbsearch.py new file mode 100644 index 0000000..15d4a24 --- /dev/null +++ b/app_alphajob/database/dbsearch.py @@ -0,0 +1,140 @@ +############################################################################ +# # +# Description: Ensemble de méthodes pour étendre dbmain afin # +# d'effectuer des recherches dans la bdd # +# # +############################################################################ + +# Infos pour les """join""": +# https:#www.freecodecamp.org/news/sql-joins-tutorial/ + +# Import de dbmain +from . import dbmain + + +# Extension de cette classe avec dbmain +class DbSearch(dbmain.DbMain): + # **************************************************************************** + # RECUPERATION DES INFORMATIONS RELATIVES AUX UTILISATEURS + # **************************************************************************** + # Récupération des infos d'un compte par son id + def get_user_account_by_userid(self, userId): + reqSearchUser = """ + SELECT + userId, email, inscriptionDate, userStatus + FROM + """ + self.TABLEUSERACCOUNT + """ + WHERE + userId = %s""" + self.exec_cmd(reqSearchUser, [userId]) + return self.cur.fetchall() + + # Récupération des infos d'un utilisateur par son id + def get_user_info_by_userid(self, userId): + reqGetUserInfo = """ + SELECT + userId, lastname, firstname, degree, + capability, description, phoneNumber, + adress, zipCode, city + FROM + """ + self.TABLEUSERINFO + """ + WHERE + userId = %s""" + self.exec_cmd(reqGetUserInfo, [userId]) + return self.cur.fetchall() + + # **************************************************************************** + # RECUPERATION DES INFORMATIONS RELATIVES AUX PROS + # **************************************************************************** + def get_all_pro_by_jobid(self, jobId): + reqSearchConsultant = """ + SELECT + """ + self.TABLEUSERINFO + """.userId, + lastname, firstname, capability + FROM + """ + self.TABLEUSERINFO + """ + INNER JOIN + """ + self.TABLEUSERJOB + """ + ON + """ + self.TABLEUSERINFO + """.userId = """ + self.TABLEUSERJOB + """.userId + WHERE + jobCategoryId = %s""" + self.exec_cmd(reqSearchConsultant, [jobId]) + return self.cur.fetchall() + + # Récupération des infos d'un pro par son nom + def get_pro_info_by_lastname(self, lastname): + reqSearchConsultant = """ + SELECT + """ + self.TABLEUSERINFO + """.userId, + lastname, firstname, capability + FROM + """ + self.TABLEUSERINFO + """ + INNER JOIN + """ + self.TABLEUSERACCOUNT + """ + ON + """ + self.TABLEUSERINFO + """.userId = """ + self.TABLEUSERACCOUNT + """.userId + WHERE + userStatus = '1' + AND + lastname LIKE CONCAT('%', %s, '%')""" + self.exec_cmd(reqSearchConsultant, [lastname]) + return self.cur.fetchall() + + # Récupération des emploies associés à un pro + def get_pro_job_by_proid(self, proId): + reqGetAll = """ + SELECT + """ + self.TABLEUSERJOB + """.jobCategoryId, + jobCategoryNameEn, jobCategoryNameFr + FROM + """ + self.TABLEUSERJOB + """ + INNER JOIN + """ + self.TABLEJOBCATEGORY + """ + ON + """ + self.TABLEUSERJOB + """.jobCategoryId = """ + self.TABLEJOBCATEGORY + """.jobCategoryId + WHERE + userId = %s""" + self.exec_cmd(reqGetAll, [proId]) + return self.cur.fetchall() + + # Récupération des notes d'un consultant par son nom + def get_pro_note_by_proid(self, proId): + reqCountMission = """ + SELECT + note + FROM + """ + self.TABLEMISSION + """ + INNER JOIN + """ + self.TABLEUSERINFO + """ + ON + """ + self.TABLEMISSION + """.proId = """ + self.TABLEUSERINFO + """.userId + WHERE + proId = %s""" + self.exec_cmd(reqCountMission, [proId]) + return self.cur.fetchall() + + # **************************************************************************** + # RECUPERATION DES INFORMATIONS RELATIVES AUX EMPLOIS + # **************************************************************************** + # Récupérer toutes les infos de la table jobCategory + def get_job_all(self): + reqGetAllJobs = """ + SELECT + * + FROM + """ + self.TABLEJOBCATEGORY + self.exec_cmd(reqGetAllJobs) + return self.cur.fetchall() + + # Récupérer toutes les infos de la table jobCategory + def get_job_by_jobid(self, jobId): + reqGetJobinfo = """ + SELECT + * + FROM + """ + self.TABLEJOBCATEGORY + """ + WHERE + jobCategoryId = %s""" + self.exec_cmd(reqGetJobinfo, [jobId]) + return self.cur.fetchall() diff --git a/app_alphajob/database/dbuser.py b/app_alphajob/database/dbuser.py new file mode 100644 index 0000000..e0a62fb --- /dev/null +++ b/app_alphajob/database/dbuser.py @@ -0,0 +1,171 @@ + + +############################################################################ +# # +# Description: Ensemble de méthodes pour étendre dbmain # +# afin de gérer les utilisateurs # +# # +############################################################################ + +from datetime import datetime +from passlib.hash import sha512_crypt +# Import de dbmain +from . import dbmain + +# Extension de cette classe avec dbmain +class DbUser(dbmain.DbMain): + + # **************************************************************************** + # GESTION DES UTILISATEURS + # **************************************************************************** + # Enregistrement d'un nouvel utilisateur + def register_user(self, email, password, userStatus): + # On vérifie si l'email existe deja dans la bdd + exist = self.check_exist_email(email) + # Si non + if not exist: + # Chiffrement du pass + hash = self.crypt_pass(password) + # Préparation de la requète + reqAddUser = """"" + INSERT INTO + """ + self.TABLEUSERACCOUNT + """ + (email, password, inscriptionDate, userStatus) + VALUES + (%s, %s, %s, %s)""" + # Execution de la requète + self.exec_cmd(reqAddUser, + [email, + hash, + datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + userStatus + ] + ) + # Retourne 1 pour réussite + return 1 + else: + # Retourne 0 pour échec + return 0 + + # Vérification de la combinaison email - pass pour authentification + def check_user_credential(self, email, password): + # Préparation de la requète pour récupérer les infos ou l'email est présent + reqCheckCredential = """ + SELECT + userId, password + FROM + """ + self.TABLEUSERACCOUNT + """ + WHERE + email = %s """ + # Execution de la requète + self.exec_cmd(reqCheckCredential, [email]) + result = self.cur.fetchone() + # Vérifiaction de correspondance email & pass + if result and sha512_crypt.verify(password, result[1]): + return result[0] + + # Mise à jour des infos d'un utilisateur + def update_user_infos(self, userInfos, userId, isPro, userJobs=None): + # Préparation de la requète pour mise à jour des infos + # J'ai préféré faire deux requètes distinctes et ne pas utiliser des valeurs + # passées par POST (key => value) pour gérer les noms des colonnes + # car je préfère les passer en "dur" dans mes requêtes (risque d'injection SQL%s). + reqAddInfoClient = """ + REPLACE INTO + """ + self.TABLEUSERINFO + """ + (lastname, firstname, phoneNumber, + adress, zipCode, city, userId) + VALUES + (%s, %s, %s, %s, %s, %s, %s)""" + reqAddInfoPro = """ + REPLACE INTO + """ + self.TABLEUSERINFO + """ + (lastname, firstname, phoneNumber, + adress, zipCode, city, degree, + capability, description, userId) + VALUES + (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""" + reqAddInfoProJobs = """ + INSERT INTO + """ + self.TABLEUSERJOB + """ + (jobCategoryId, userId) + VALUES + (%s, %s)""" + reqRemoveInfoProJobs = """ + DELETE FROM + """ + self.tableUserJob + """ + WHERE + jobCategoryId = %s + AND + userId = %s""" + # if not isPro: + # # Exécution de la requète + # # https:#www.php.net/manual/fr/function.array-values.php + # # Pour passer de "dict" a "list" -> array_values() + # args = [i for i in userInfos] + # args.push(userId) + # self.exec_cmd(reqAddInfoClient, args) + # else: + # # https:#stackoverflow.com/questions/15986235/how-to-use-json-stringify-and-json-decode-properly + # # Récupération des emplois dans le JSON et supression de ces derniers de la liste + # selectedJobs = json_decode(html_entity_decode(userInfos["jobs"])) + # unset(userInfos["jobs"]) + # # array_value -> Qu'est ce qui est présent dans 1 mais pas dans 2 %s + # # Comparaison des jobs anciennement présent avec ceux sélectionnés, donc ajoutés. + # jobsAdded = array_values(array_diff(selectedJobs, userJobs)) + # # Comparaison des jobs deja présent avec ceux sélectionnés, donc ajoutés. + # jobsRemoved = array_values(array_diff(userJobs, selectedJobs)) + # # on continue classiquement avec les autres éléments + # args = array_values(userInfos) + # array_push(args, userId) + # self.exec_cmd(reqAddInfoPro, args) + # for i in jobsAdded: + # self.exec_cmd(reqAddInfoProJobs, array(jobsAdded[i], userId)) + # for i in jobsRemoved: + # self.exec_cmd(reqRemoveInfoProJobs, array(jobsRemoved[i], userId)) + + # **************************************************************************** + # GESTION DU TOKEN AUTOLOGIN + # **************************************************************************** + # Vérification de la combinaison email - jeton d'auto-login pour authentification + def check_token_autologin(self, email, token): + # Préparation de la requète pour récupérer les infos ou l'email est présent + reqCheckToken = """ + SELECT + userId, tokenAutoLogin + FROM + """ + self.TABLEUSERACCOUNT + """ + WHERE + email = %s""" + # Exécution de la requète + self.exec_cmd(reqCheckToken, [email]) + result = self.cur.fetchone() + # Vérifiaction de correspondance email & jeton d'auto-connection + if result and result[1] == token: + return result[0] + + # Mise à jour du jeton d'auto-login + def update_token_autologin(self, email, token): + # Préparation de la requète pour mise à jour du jeton d'auto-connection + reqUpdateToken = """ + UPDATE + """ + self.TABLEUSERACCOUNT + """ + SET + tokenAutoLogin = %s + WHERE + email = %s""" + # Execution de la requète + self.exec_cmd(reqUpdateToken, [token, email]) + + # Supression du jeton d'auto-login + def del_token_autologin(self, email): + # Préparation de la requète pour supression du jeton d'auto-connection + reqDeleteToken = """ + UPDATE + """ + self.TABLEUSERACCOUNT + """ + SET + tokenAutoLogin = NULL + WHERE + email = %s""" + # Execution de la requète + self.exec_cmd(reqDeleteToken, [email]) diff --git a/app_alphajob/main.py b/app_alphajob/main.py new file mode 100644 index 0000000..11f4cc1 --- /dev/null +++ b/app_alphajob/main.py @@ -0,0 +1,119 @@ + + +import sys +from os.path import join +from PyQt5 import QtWidgets, QtGui +from database import dbuser + +class mainWindow(QtWidgets.QMainWindow): + + VERSION = 0.1 + + def __init__(self): + super(mainWindow, self).__init__() + logo = join("./ressources", "icon.ico") + self.setWindowIcon(QtGui.QIcon(logo)) + menu = self.menuBar() + menu_options = menu.addMenu("Options") + btn_apropos = QtWidgets.QAction("A propos", self) + btn_apropos.triggered.connect(self.a_propos) + menu_options.addAction(btn_apropos) + self.setWindowTitle("Alphajob") + self.home() + + def home(self): + self.label1 = QtWidgets.QLabel("Home page") + btn1 = QtWidgets.QPushButton("Aller à la page de connexion") + btn1.clicked.connect(self.page_login) + + self.layoutMain = QtWidgets.QVBoxLayout() + + self.layoutMain.addWidget(self.label1) + self.layoutMain.addWidget(btn1) + + if hasattr(self, "mainWidget"): + self.mainWidget.deleteLater() + self.mainWidget = QtWidgets.QWidget() + self.mainWidget.setLayout(self.layoutMain) + self.setCentralWidget(self.mainWidget) + self.show() + + def page_login(self): + btnAccueil = QtWidgets.QPushButton("Accueil") + btnAccueil.clicked.connect(self.home) + self.emailConnexion = QtWidgets.QLineEdit("Email") + self.passwordConnexion = QtWidgets.QLineEdit("Password") + btnConnexion = QtWidgets.QPushButton("Connexion") + btnConnexion.clicked.connect(self.login) + + self.layoutMain = QtWidgets.QVBoxLayout() + self.layoutNavigation = QtWidgets.QHBoxLayout() + self.layoutPassword = QtWidgets.QHBoxLayout() + self.layoutPasswordWidgets = QtWidgets.QVBoxLayout() + + self.layoutMain.addLayout(self.layoutNavigation) + self.layoutNavigation.addWidget(btnAccueil) + self.layoutNavigation.addStretch() + + self.layoutMain.addLayout(self.layoutPassword) + self.layoutPassword.addStretch() + self.layoutPassword.addLayout(self.layoutPasswordWidgets) + self.layoutPassword.addStretch() + + self.layoutPasswordWidgets.addWidget(self.emailConnexion) + self.layoutPasswordWidgets.addWidget(self.passwordConnexion) + self.layoutPasswordWidgets.addWidget(btnConnexion) + + self.mainWidget.deleteLater() + self.mainWidget = QtWidgets.QWidget() + self.mainWidget.setLayout(self.layoutMain) + self.setCentralWidget(self.mainWidget) + + def login(self): + user = dbuser.DbUser() + if user.check_exist_email(self.emailConnexion.text()): + res = user.check_user_credential( + self.emailConnexion.text(), + self.passwordConnexion.text() + ) + if res: + QtWidgets.QMessageBox.information( + self, + "Connexion", + "Vous êtes connecté" + ) + else: + QtWidgets.QMessageBox.warning( + self, + "Connexion", + "Mauvaise combinaison mail & mot de passe" + ) + else: + QtWidgets.QMessageBox.warning( + self, + "Connexion", + "Mauvais email" + ) + + + def a_propos(self): + QtWidgets.QMessageBox.information( + self, + "A propos", + "Logiciel pour mon dossier professionnel.\ + <br>Version: %s\ + <br>Auteur: Debulois Quentin\ + <br>Code source: \ + <a href='https://git.debulois.fr/'>git.debulois.fr/</a>" % self.VERSION + ) + + +if __name__ == "__main__": + def main(): + """Démarrage de l'app + """ + app = QtWidgets.QApplication(sys.argv) + GUI = mainWindow() + sys.exit(app.exec_()) + + main()
\ No newline at end of file diff --git a/app_alphajob/ressources/icon.ico b/app_alphajob/ressources/icon.ico Binary files differnew file mode 100644 index 0000000..7c550a3 --- /dev/null +++ b/app_alphajob/ressources/icon.ico diff --git a/requierments.txt b/requierments.txt Binary files differnew file mode 100644 index 0000000..a7e7164 --- /dev/null +++ b/requierments.txt |
