Valentin Moguérou
1 year ago
6 changed files with 167 additions and 38 deletions
@ -0,0 +1,30 @@ |
|||
import os |
|||
import sys |
|||
from datetime import datetime |
|||
|
|||
from flask import Flask |
|||
|
|||
from .views import views |
|||
from .database import Database |
|||
|
|||
def create_app(): |
|||
sys.path.insert(0, os.path.dirname(__file__)) |
|||
|
|||
app = Flask(__name__) |
|||
app.config.from_object("config") |
|||
|
|||
app.jinja_env.globals.update({ |
|||
"year": datetime.now().year, |
|||
"menuitems": [ |
|||
('/', '<i class="fa-solid fa-house-chimney"></i>', 'accueil'), |
|||
('/grades/', 'Mes notes', ''), |
|||
('/timetable/', 'Emploi du temps', '') |
|||
] |
|||
}) |
|||
|
|||
db = Database(app) |
|||
views(app, db) |
|||
|
|||
return app |
|||
|
|||
app = create_app() |
@ -0,0 +1,63 @@ |
|||
from uuid import uuid4 |
|||
|
|||
import mysql.connector |
|||
|
|||
class Database: |
|||
def __init__(self, app): |
|||
self.db = mysql.connector.connect( |
|||
host=app.config["DB_HOSTNAME"], |
|||
user=app.config["DB_USERNAME"], |
|||
password=app.config["DB_PASSWORD"], |
|||
database=app.config["DB_DATABASE"] |
|||
) |
|||
|
|||
def delete_old_sessions(self): |
|||
cursor = self.db.cursor() |
|||
cursor.execute("DELETE FROM sessions WHERE expiry_date <= CURRENT_TIMESTAMP") |
|||
self.db.commit() |
|||
|
|||
def create_session(self, username, password): |
|||
cursor = self.db.cursor() |
|||
cursor.execute("SELECT user_id FROM utilisateurs WHERE username=%s AND password=%s", (username, password)) |
|||
|
|||
if result := cursor.fetchall(): |
|||
user_id = result[0][0] |
|||
else: |
|||
return None |
|||
|
|||
uuid = str(uuid4()) |
|||
cursor.execute("INSERT INTO sessions (session_id, user_id) VALUES (%s, %s)", (uuid, user_id)) |
|||
self.db.commit() |
|||
|
|||
return uuid |
|||
|
|||
def destroy_session(self, uuid): |
|||
cursor = self.db.cursor() |
|||
cursor.execute("DELETE FROM sessions WHERE session_id=%s", (uuid,)) |
|||
self.db.commit() |
|||
|
|||
def check_connection(self, uuid): |
|||
cursor = self.db.cursor() |
|||
cursor.execute("SELECT session_id FROM sessions WHERE session_id=%s", (uuid,)) |
|||
|
|||
return cursor.fetchall() |
|||
|
|||
class User: |
|||
def __init__(self, user_id, username, nom, prenom, creation_date): |
|||
self.id = user_id |
|||
self.username = username |
|||
self.nom = nom |
|||
self.prenom = prenom |
|||
self.creation_date = creation_date |
|||
|
|||
class Session: |
|||
def __init__(self, db, uuid): |
|||
self.db = db |
|||
self.uuid = uuid |
|||
self.user = self.get_user() |
|||
|
|||
def get_user(self): |
|||
cursor = self.db.db.cursor() |
|||
cursor.execute("SELECT utilisateurs.user_id, username, nom, prenom, creation_date FROM utilisateurs " |
|||
"JOIN sessions ON utilisateurs.user_id=sessions.user_id WHERE session_id=%s", (self.uuid,)) |
|||
self.user = User(*cursor.fetchall()[0]) |
@ -0,0 +1,17 @@ |
|||
<!doctype html> |
|||
<html lang="fr"> |
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<meta name="viewport" |
|||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> |
|||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> |
|||
<title>Se connecter</title> |
|||
</head> |
|||
<body> |
|||
<form method="post"> |
|||
<input type="text" name="username"> |
|||
<input type="password" name="password"> |
|||
<input type="submit"> |
|||
</form> |
|||
</body> |
|||
</html> |
@ -1,37 +1,55 @@ |
|||
from flask import Flask, request, session |
|||
from flask import render_template, send_from_directory |
|||
import os |
|||
import sys |
|||
|
|||
from datetime import datetime |
|||
|
|||
sys.path.insert(0, os.path.dirname(__file__)) |
|||
|
|||
app = Flask(__name__) |
|||
app.config.from_object("config") |
|||
|
|||
app.jinja_env.globals.update({ |
|||
"year": datetime.now().year, |
|||
"menuitems": [ |
|||
('/', '<i class="fa-solid fa-house-chimney"></i>', 'accueil'), |
|||
('/grades/', 'Mes notes', ''), |
|||
('/timetable/', 'Emploi du temps', '') |
|||
] |
|||
}) |
|||
|
|||
@app.route("/") |
|||
def index(): |
|||
return render_template("index.html") |
|||
|
|||
@app.route("/grades/") |
|||
def grades(): |
|||
return render_template("grades.html") |
|||
|
|||
@app.route("/timetable/") |
|||
def timetable(): |
|||
return render_template("timetable.html") |
|||
|
|||
@app.route('/favicon.ico') |
|||
def favicon(): |
|||
return send_from_directory(os.path.join(app.root_path, 'static'), |
|||
'favicon.ico',mimetype='image/vnd.microsoft.icon') |
|||
from hashlib import sha256 |
|||
from functools import wraps |
|||
|
|||
from flask import render_template, send_from_directory, request, session, redirect |
|||
|
|||
from .database import Session |
|||
|
|||
def views(app, db): |
|||
def est_connecte(): |
|||
return session.get("uuid") is not None and db.check_connection(session.get("uuid")) |
|||
|
|||
def login_required(func): |
|||
@wraps(func) |
|||
def wrapper(*args, **kwargs): |
|||
return func(*args, **kwargs) if est_connecte() else redirect("/login") |
|||
return wrapper |
|||
@app.route("/") |
|||
@login_required |
|||
def index(): |
|||
return render_template("index.html", s=Session(db, session["uuid"])) |
|||
|
|||
@app.route("/login/", methods=["GET"]) |
|||
def login_get(): |
|||
return render_template("login.html") |
|||
|
|||
@app.route("/login/", methods=["POST"]) |
|||
def login_post(): |
|||
session["uuid"] = db.create_session( |
|||
request.form["username"], |
|||
sha256(request.form["password"].encode()).hexdigest() |
|||
) |
|||
return redirect("/") |
|||
|
|||
@app.route("/logout/") |
|||
@login_required |
|||
def logout(): |
|||
db.destroy_session(session["uuid"]) |
|||
session["uuid"] = None |
|||
return redirect("/login/") |
|||
|
|||
@app.route("/grades/") |
|||
@login_required |
|||
def grades(): |
|||
return render_template("grades.html", s=Session(db, session["uuid"])) |
|||
|
|||
@app.route("/timetable/") |
|||
@login_required |
|||
def timetable(): |
|||
return render_template("timetable.html", s=Session(db, session["uuid"])) |
|||
|
|||
@app.route('/favicon.ico') |
|||
def favicon(): |
|||
return send_from_directory(os.path.join(app.root_path, 'static'), |
|||
'favicon.ico', mimetype='image/vnd.microsoft.icon') |
|||
|
Loading…
Reference in new issue