diff --git a/README.md b/README.md index d6c6405..961bc41 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# loustique-home +Toujours run "run_flasj.sh par facilité et pour que script rende $SUDO_USERS ou $USER propriétaire du fichier log diff --git a/flask/__pycache__/add_user.cpython-311.pyc b/flask/__pycache__/add_user.cpython-311.pyc new file mode 100644 index 0000000..dc320a3 Binary files /dev/null and b/flask/__pycache__/add_user.cpython-311.pyc differ diff --git a/flask/__pycache__/auth.cpython-311.pyc b/flask/__pycache__/auth.cpython-311.pyc index 27b1fcc..eb54ede 100644 Binary files a/flask/__pycache__/auth.cpython-311.pyc and b/flask/__pycache__/auth.cpython-311.pyc differ diff --git a/flask/__pycache__/led.cpython-311.pyc b/flask/__pycache__/led.cpython-311.pyc new file mode 100644 index 0000000..0a55ac8 Binary files /dev/null and b/flask/__pycache__/led.cpython-311.pyc differ diff --git a/flask/__pycache__/log.cpython-311.pyc b/flask/__pycache__/log.cpython-311.pyc new file mode 100644 index 0000000..4a1b600 Binary files /dev/null and b/flask/__pycache__/log.cpython-311.pyc differ diff --git a/flask/add_user.py b/flask/add_user.py index de0bdda..0b5753d 100644 --- a/flask/add_user.py +++ b/flask/add_user.py @@ -4,6 +4,7 @@ import bcrypt from dotenv import load_dotenv from datetime import datetime import os +from log import log load_dotenv() @@ -20,32 +21,28 @@ def init(): return conn except pymysql.err.OperationalError as e: - print(f"❌ Erreur de connexion : {e}") + print(f"Erreur de connexion : {e}") + log.error(f"Erreur de connexion : {e}") return None -def add(): +def add_user(username, password, role): conn = init() if conn is None: return False - - username = input("Quel est l'username du nouvel utilisateur : ") - password = getpass.getpass("Quel est le password : ") - - # Hashage du mot de passe avec bcrypt + hashed = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()) + try: cursor = conn.cursor() - requete = "INSERT INTO Auth (username, password, created_at) VALUES (%s, %s, %s)" - cursor.execute(requete, (username, hashed, datetime.now())) + requete = "INSERT INTO Auth (username, password, Fonctions, created_at) VALUES (%s, %s, %s, %s)" + cursor.execute(requete, (username, hashed, role, datetime.now())) conn.commit() - print(f"✅ Utilisateur '{username}' ajouté avec succès !") - + log.info(f"Utilisateur '{username}' ({role}) ajouté") + return True except pymysql.err.IntegrityError: - print("❌ Cet utilisateur existe déjà") - + log.error(f"Utilisateur existant : {username}") + return False finally: cursor.close() - conn.close() - -add() + conn.close() \ No newline at end of file diff --git a/flask/auth.py b/flask/auth.py index 2f50de8..9fddf47 100644 --- a/flask/auth.py +++ b/flask/auth.py @@ -3,6 +3,7 @@ import getpass import bcrypt from dotenv import load_dotenv import os +from log import log load_dotenv() @@ -17,19 +18,16 @@ def init(): charset=os.getenv("DB_CHARSET", "utf8mb4") ) return conn - except pymysql.err.OperationalError as e: - print(f"❌ Erreur de connexion : {e}") + print(f"Erreur de connexion : {e}") + log.error(f"Erreur de connexion : {e}") return None -def login(username,password): - #username = input("Username : ") - #password = getpass.getpass("Mot de passe : ") +def login(username, password): conn = init() if conn is None: return False - try: cursor = conn.cursor() requete = "SELECT password FROM Auth WHERE username = %s" @@ -37,17 +35,33 @@ def login(username,password): resultat = cursor.fetchone() if resultat and bcrypt.checkpw(password.encode('utf-8'), resultat[0].encode('utf-8')): print("Connexion réussie") + log.info(f"Connexion réussie pour {username}") return True else: - print(" Identifiants incorrects") + print("Identifiants incorrects") + log.info("Identifiants incorrects,il est trop nul") return False - except pymysql.err.OperationalError as e: print(f"Erreur : {e}") + log.error(f"Erreur SQL : {e}") return False - finally: cursor.close() conn.close() +def get_users(): + conn = init() + if conn is None: + return [] + try: + cursor = conn.cursor() + cursor.execute("SELECT username, Fonctions, created_at FROM Auth") + users = cursor.fetchall() + return [{"username": u[0], "role": u[1], "created_at": str(u[2])} for u in users] + except pymysql.err.OperationalError as e: + log.error(f"Erreur get_users : {e}") + return [] + finally: + cursor.close() + conn.close() \ No newline at end of file diff --git a/flask/bouton.py b/flask/bouton.py deleted file mode 100644 index 0c1f546..0000000 --- a/flask/bouton.py +++ /dev/null @@ -1,22 +0,0 @@ -from time import * -from gpiozero import * -from signal import pause - -def led (): - print ('led allumé') - """ - print("One button to turn on or off") - - led = LED(17) - btn = Button(20, bounce_time=None) - - while True: - print('turn on') - led.on() - sleep(0.2) # to avoid bouncing - btn.wait_for_press() - print('turn off') - led.off() - sleep(0.2) # to avoid bouncing - btn.wait_for_press() - """ diff --git a/flask/led.py b/flask/led.py new file mode 100644 index 0000000..ef06c41 --- /dev/null +++ b/flask/led.py @@ -0,0 +1,22 @@ +from time import * +from gpiozero import * +from signal import pause +from log import log + +def led(utilisateur): + print('led allumé') + log.info(f'led allumé par {utilisateur}') + """ + print("One button to turn on or off") + led = LED(17) + btn = Button(20, bounce_time=None) + while True: + print('turn on') + led.on() + sleep(0.2) # to avoid bouncing + btn.wait_for_press() + print('turn off') + led.off() + sleep(0.2) # to avoid bouncing + btn.wait_for_press() + """ \ No newline at end of file diff --git a/flask/log.py b/flask/log.py index 80964c8..9e4a755 100644 --- a/flask/log.py +++ b/flask/log.py @@ -1,10 +1,19 @@ -import logging - -logging.basicConfig( -filename='/var/log/loustique.log', -filemode='a', -format='%(asctime)s - %(name)s - %(levelname)/s - %(message)/s', -level=logging.DEBUG) +import logging +def setup_log(): + logger = logging.getLogger("loustique") + logger.setLevel(logging.DEBUG) + + handler = logging.FileHandler('/var/log/loustique.log') + formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') + handler.setFormatter(formatter) + logger.addHandler(handler) + logger.propagate = False + werkzeug_logger = logging.getLogger('werkzeug') + werkzeug_logger.handlers = [] + werkzeug_logger.addHandler(handler) + werkzeug_logger.propagate = False + return logger +log = setup_log() \ No newline at end of file diff --git a/flask/main.py b/flask/main.py index 12acce6..77757f3 100644 --- a/flask/main.py +++ b/flask/main.py @@ -1,30 +1,71 @@ -from flask import Flask,render_template,request, jsonify -from bouton import led -import time +from flask import Flask, render_template, request, jsonify +from led import led import os -import auth +from add_user import add_user +import auth +import re + app = Flask(__name__) + +current_user = None + @app.route("/") def index(): - return render_template("index.html") + return render_template("index.html") @app.route("/login", methods=["POST"]) def login(): + global current_user data = request.get_json() succes = auth.login(data["username"], data["password"]) if succes: - return jsonify({"success": True, "message": "Connexion réussie"}) - + current_user = data["username"] + return jsonify({"success": True}) else: - return jsonify({"success": False, "message": "Identifiants incorrects"}) + return jsonify({"success": False}) + @app.route("/dashboard") def dashboard(): - return render_template("dashboard.html") + return render_template("dashboard.html") -@app.route("/led") +@app.route("/led", methods=["POST"]) def call_led(): - led() - return "import bouton réussi" -if __name__ == "__main__": - app.run(host="0.0.0.0", port=5000) + led(current_user) + return jsonify({"success": True}) +@app.route("/admin") +def admin_page(): + return render_template("admin.html") + +@app.route("/admin/logs") +def logs_page(): + return render_template("log.html") + + +@app.route("/admin/logs/data") +def get_logs(): + try: + with open('/var/log/loustique.log', 'r') as f: + lines = f.readlines() + ansi_escape = re.compile(r'\x1b\[[0-9;]*m') + lines = [ansi_escape.sub('', line) for line in lines[-200:]] + return jsonify({"success": True, "logs": lines}) + except Exception as e: + return jsonify({"success": False, "message": str(e)}) + +@app.route("/admin/add_user",methods=["POST"]) +@app.route("/admin/add_user", methods=["POST"]) +def create_user(): + data = request.get_json() + succes = add_user(data["username"], data["password"], data["role"]) + if succes: + return jsonify({"success": True}) + else: + return jsonify({"success": False, "message": "Utilisateur déjà existant"}) +@app.route("/admin/get_users") +def get_users(): + users = auth.get_users() + return jsonify({"success": True, "users": users}) + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=5000) \ No newline at end of file diff --git a/flask/templates/admin.html b/flask/templates/admin.html new file mode 100644 index 0000000..6e91f6b --- /dev/null +++ b/flask/templates/admin.html @@ -0,0 +1,497 @@ + + + + + + Admin — Loustiques + + + + + + + +
+ + +
+
Créer un utilisateur
+
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
+
+ +
+
+ +
+
Comptes existants
+
+
+
MA
+ + admin + +
+
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/flask/templates/dashboard.html b/flask/templates/dashboard.html index dc22954..4b07254 100644 --- a/flask/templates/dashboard.html +++ b/flask/templates/dashboard.html @@ -156,16 +156,17 @@ animation: fadeUp 0.5s 0.45s ease both; } - .action-btn { - background: var(--panel); - border: 1px solid var(--border); - border-radius: 2px; - padding: 18px 20px; - cursor: pointer; - text-align: left; - transition: border-color 0.2s, background 0.2s, transform 0.1s; - position: relative; overflow: hidden; - } + .action-btn { + background: var(--panel); + border: 1px solid var(--border); + border-radius: 2px; + padding: 18px 20px; + cursor: pointer; + text-align: left; + transition: border-color 0.2s, background 0.2s, transform 0.1s; + position: relative; overflow: hidden; + color: var(--text); /* ← ajouter ça */ +} .action-btn:hover { border-color: var(--accent); background: rgba(124,106,255,0.05); } .action-btn:active { transform: scale(0.98); } @@ -261,6 +262,11 @@ État de la connexion + @@ -270,7 +276,7 @@ + + \ No newline at end of file diff --git a/run_flask.sh b/run_flask.sh index 4f9be13..2ba6893 100755 --- a/run_flask.sh +++ b/run_flask.sh @@ -47,4 +47,6 @@ Lancement du serveur FLASK EOF sleep 1 +touch /var/log/loustique.log +chown ${SUDO_USER}:${SUDO_USER} /var/log/loustique.log venv/bin/python ./flask/main.py