gmao/app_new/core/routes/auth.py
root d3ddfdb974
Some checks are pending
CI - Tests et Syntax / lint-and-test (push) Waiting to run
Centralise les rôles et les permissions
2026-08-14 18:53:03 +00:00

188 lines
6.5 KiB
Python

"""
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/<int:id>/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/<int:id>/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/<int:id>/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)