routes.py 2.2 KB
from functools import wraps

from flask_login import current_user
from flask import render_template, request, redirect, url_for, flash, current_app
from flask_login import login_user, logout_user

from app.auth.models import User
from app.auth import bp

main_index = 'main.index'


#
# Decorator used to protect routes by role
# inspired from https://flask.palletsprojects.com/en/master/patterns/viewdecorators/
#
def role_required(role):
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            try:
                if current_app.config['ROLE_DISABLED']:
                    return f(*args, **kwargs)
            except KeyError:
                # no such config, juste ignore
                pass
            # first check use is logged in
            if not current_user or not current_user.is_authenticated:
                flash(f"Vous devez vous authentifier avec la fonction '{role}'", 'warning')
                return redirect(url_for('auth.login'))
            # then check role status
            try:
                is_authorised = current_user.has_role_or_higher(role)
            except ValueError:
                raise ValueError("Unknown role provided %s" % role)
            if not is_authorised:
                flash("Vous n'avez pas les autorisations pour accéder à cette page", 'dark')
                return redirect(url_for(main_index))
            return f(*args, **kwargs)

        return decorated_function

    return decorator


@bp.route('/login')
def login():
    return render_template('login.html', title="Login")


@bp.route('/login', methods=['POST'])
def login_post():
    user_login = request.form.get('login')
    user_password = request.form.get('password')
    user = User.query.filter_by(login=user_login).one_or_none()
    if user and user.check_password(user_password):
        login_user(user)
        flash("Connection Réussie !", 'success')
        return redirect(url_for(main_index))
    else:
        flash("Mauvais login ou mot de passe.", 'warning')
        return redirect(url_for('auth.login'))


@bp.route('/logout')
def logout():
    logout_user()
    flash("Vous êtes maintenant déconnecté", 'info')
    return redirect(url_for(main_index))