#!/usr/bin/env python3 import re from flask import ( Flask, Response, redirect, render_template_string, request, session, url_for, ) app = Flask(__name__) app.secret_key = "super_secret_training_key_2025" # Dictionnaire des utilisateurs : username -> password users = { "user1": "aaaaa", # 5 caractères "user2": "rock12", # exemple autre mot de passe "user3": "secret", "user4": "#-1234abcd-#", # mot de passe niveau 4 } # Page de connexion avec sélecteur de niveau + Tailwind + Logo login_page = """ Authentification
Logo

Connexion

{% if error %}

{{ error }}

{% endif %}
Mot de passe oublié ?
""" # Page d'accueil Niveau 1 home_page_level1 = """ Accueil Niveau 1
Logo

Bienvenue, {{ username }} !

Vous êtes connecté au Niveau 1.

Mot de passe de 5 caractères.

Déconnexion
""" # Page d'accueil Niveau 2 home_page_level2 = """ Accueil Niveau 2
Logo

Bienvenue, {{ username }} !

Vous êtes connecté au Niveau 2.

Mot de passe : "rock12".

Déconnexion
""" # Page d'accueil Niveau 3 home_page_level3 = """ Accueil Niveau 3
Logo

Bienvenue, {{ username }} !

Vous êtes connecté au Niveau 3.

En cas de "mot de passe oublié", le hash MD5 vous sera fourni.

Déconnexion
""" # Page d'accueil Niveau 4 home_page_level4 = """ Accueil Niveau 4
Logo

Bienvenue, {{ username }} !

Vous êtes connecté au Niveau 4.

Votre mot de passe doit respecter le format : "#-[0-9]{4}[a-z]{4}-#".

Déconnexion
""" # Page "mot de passe oublié" (indice seulement si l'utilisateur est user4) forgot_page = """ Mot de passe oublié
Logo

Mot de passe oublié

{% if message %}

{{ message }}

{% else %}
{% endif %}
Retour à la connexion
""" @app.route("/", methods=["GET", "POST"]) @app.route("/login", methods=["GET", "POST"]) def login() -> Response: """Page de connexion avec sélection du niveau.""" error = None if request.method == "POST": username = request.form.get("username") password = request.form.get("password") level_str = request.form.get("level") # Vérifier que l'utilisateur existe if username in users: # Vérifier le mot de passe if users[username] == password: # Le niveau est choisi par l'utilisateur (pas stocké dans le dictionnaire) try: level = int(level_str) except (ValueError, TypeError): error = "Sélectionnez un niveau valide." return render_template_string(login_page, error=error) # On enregistre le niveau choisi dans la session session["username"] = username session["level"] = level # Redirection vers la page correspondant au niveau if level == 1: return redirect(url_for("home1")) if level == 2: return redirect(url_for("home2")) if level == 3: return redirect(url_for("home3")) if level == 4: return redirect(url_for("home4")) else: error = "Mot de passe incorrect." else: error = "Utilisateur inconnu." return render_template_string(login_page, error=error) @app.route("/home1") def home1() -> Response: """Page d'accueil pour le niveau 1.""" if "username" in session and session.get("level") == 1: return render_template_string(home_page_level1, username=session["username"]) return redirect(url_for("login")) @app.route("/home2") def home2() -> Response: """Page d'accueil pour le niveau 2.""" if "username" in session and session.get("level") == 2: return render_template_string(home_page_level2, username=session["username"]) return redirect(url_for("login")) @app.route("/home3") def home3() -> Response: """Page d'accueil pour le niveau 3.""" if "username" in session and session.get("level") == 3: return render_template_string(home_page_level3, username=session["username"]) return redirect(url_for("login")) @app.route("/home4") def home4() -> str: """Page d'accueil pour le niveau 4.""" if "username" in session and session.get("level") == 4: return render_template_string(home_page_level4, username=session["username"]) return redirect(url_for("login")) @app.route("/logout") def logout() -> str: """Déconnexion de l'utilisateur.""" session.pop("username", None) session.pop("level", None) return redirect(url_for("login")) @app.route("/forgot", methods=["GET", "POST"]) def forgot() -> str: """Seul user4 reçoit un indice. Les autres utilisateurs n'ont pas d'indice. """ message = None if request.method == "POST": username = request.form.get("username") if username in users: # Seul user4 a droit à un indice (puisque c'est le "niveau 4") if username == "user4": pattern = r"^#-[0-9]{4}[a-z]{4}-#$" if re.match(pattern, users[username]): message = ("Indice : Le mot de passe respecte le format " "'#-MDP 8 caractères max -#' (exemple : '#-1234abcd-#').") else: message = "Le mot de passe ne correspond pas au format attendu (erreur)." else: message = "Aucun indice n'est disponible pour cet utilisateur." else: message = "Utilisateur non trouvé." return render_template_string(forgot_page, message=message) if __name__ == "__main__": app.run(debug=False)