""" Core Routes - Authentification GMAO Collège """ from flask import Blueprint, render_template, redirect, url_for, request, flash from flask_login import login_user, logout_user, login_required, current_user from ...extensions import db from ..models.user import User from ..forms import LoginForm, UserForm, PasswordForm from ...constants import ROLES auth_bp = Blueprint('auth', __name__) @auth_bp.route('/login', methods=['GET', 'POST']) def login(): """Page de connexion.""" if current_user.is_authenticated: return redirect(url_for('dashboard.index')) form = LoginForm() if form.validate_on_submit(): user = User.query.filter_by(username=form.username.data).first() if user and user.check_password(form.password.data): if not user.is_active: flash("Votre compte est désactivé.", "danger") return render_template("auth/login.html", form=form) login_user(user) flash(f"Bienvenue, {user.username} !", "success") next_page = request.args.get('next', '') if not next_page.startswith('/') or next_page.startswith('//'): next_page = '' return redirect(next_page or url_for('dashboard.index')) flash("Nom d'utilisateur ou mot de passe incorrect.", "danger") return render_template('auth/login.html', form=form) @auth_bp.route('/logout') @login_required def logout(): """Déconnexion.""" logout_user() flash("Vous avez été déconnecté.", "info") return redirect(url_for('auth.login')) @auth_bp.route('/users') @login_required def list_users(): """Liste des utilisateurs.""" if not current_user.is_admin(): flash("Accès réservé aux administrateurs.", "danger") return redirect(url_for('dashboard.index')) users = User.query.order_by(User.full_name).all() return render_template('auth/users.html', users=users) @auth_bp.route('/users/new', methods=['GET', 'POST']) @login_required def create_user(): """Créer un utilisateur.""" if not current_user.is_admin(): flash("Accès réservé aux administrateurs.", "danger") return redirect(url_for('dashboard.index')) form = UserForm() if form.validate_on_submit(): user = User( username=form.username.data, email=form.email.data, full_name=form.full_name.data, role=form.role.data, is_active=form.is_active.data, ) if not form.password.data: form.password.errors.append("Un mot de passe initial est obligatoire.") return render_template('auth/user_form.html', form=form, title="Nouvel utilisateur"), 400 user.set_password(form.password.data) db.session.add(user) db.session.commit() flash(f"Utilisateur {user.full_name} créé.", "success") return redirect(url_for('auth.list_users')) return render_template('auth/user_form.html', form=form, title="Nouvel utilisateur") @auth_bp.route('/profile') @login_required def profile(): """Profil utilisateur.""" return render_template('auth/profile.html', user=current_user) @auth_bp.route('/users//edit', methods=['GET', 'POST']) @login_required def edit_user(id): """Modifier un utilisateur.""" if not current_user.is_admin(): flash("Accès réservé aux administrateurs.", "danger") return redirect(url_for('dashboard.index')) user = User.query.get_or_404(id) form = UserForm(obj=user) if form.validate_on_submit(): user.username = form.username.data user.email = form.email.data user.full_name = form.full_name.data user.role = form.role.data user.is_active = form.is_active.data if form.password.data: user.set_password(form.password.data) db.session.commit() flash(f"Utilisateur {user.full_name} modifié.", "success") return redirect(url_for('auth.list_users')) return render_template('auth/user_form.html', form=form, title="Modifier l'utilisateur") @auth_bp.route('/change-password', methods=['GET', 'POST']) @login_required def change_own_password(): """Changement de mot de passe.""" form = PasswordForm() if form.validate_on_submit(): if not current_user.check_password(form.current_password.data): flash("Mot de passe actuel incorrect.", "danger") else: current_user.set_password(form.new_password.data) db.session.commit() flash("Mot de passe modifié avec succès.", "success") return redirect(url_for('dashboard.index')) return render_template('auth/change_own_password.html', form=form) @auth_bp.route('/users//delete', methods=['POST']) @login_required def delete_user(id): """Supprimer un utilisateur.""" if not current_user.is_admin(): flash("Accès réservé aux administrateurs.", "danger") return redirect(url_for('dashboard.index')) user = User.query.get_or_404(id) if user.id == current_user.id: flash("Vous ne pouvez pas supprimer votre propre compte.", "danger") else: db.session.delete(user) db.session.commit() flash(f"Utilisateur {user.username} supprimé.", "success") return redirect(url_for('auth.list_users')) @auth_bp.route('/users//password', methods=['GET', 'POST']) @login_required def change_user_password(id): """Changer le mot de passe d'un utilisateur (admin only).""" if not current_user.is_admin(): flash("Accès réservé aux administrateurs.", "danger") return redirect(url_for('dashboard.index')) user = User.query.get_or_404(id) if request.method == 'POST': new_password = request.form.get('new_password') confirm_password = request.form.get('confirm_password') if not new_password: flash("Le mot de passe est requis.", "danger") elif new_password != confirm_password: flash("Les mots de passe ne correspondent pas.", "danger") elif len(new_password) < 12: flash("Le mot de passe doit contenir au moins 12 caractères.", "danger") else: user.set_password(new_password) db.session.commit() flash(f"Mot de passe de {user.username} modifié.", "success") return redirect(url_for('auth.list_users')) return render_template('auth/change_user_password.html', user=user)