88 lines
2.6 KiB
Python
88 lines
2.6 KiB
Python
"""
|
|
app.py — Point d'entrée de l'application GestHub.
|
|
|
|
Ce fichier ne fait qu'assembler l'application (factory pattern) : création
|
|
de l'app Flask, enregistrement des blueprints (couche routes/), du client
|
|
OAuth Keycloak, et des gestionnaires d'erreurs globaux. Aucune logique
|
|
métier ni aucun accès base de données n'a lieu ici (cf. architecture
|
|
5 couches — Bloc 1, C3).
|
|
"""
|
|
|
|
import logging
|
|
|
|
from authlib.integrations.flask_client import OAuth
|
|
from flask import Flask, jsonify, render_template
|
|
|
|
from config import Config
|
|
from db import init_db
|
|
|
|
|
|
def create_app(config_class=Config):
|
|
app = Flask(__name__)
|
|
app.config.from_object(config_class)
|
|
app.secret_key = config_class.SECRET_KEY
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
|
|
# --- Base de données (couche infrastructure) ---
|
|
db = init_db(config_class)
|
|
app.config["DB"] = db
|
|
|
|
# --- OAuth / OIDC Keycloak ---
|
|
oauth = OAuth(app)
|
|
|
|
# --- Blueprints (couche routes/) ---
|
|
from routes.auth import init_auth_routes
|
|
from routes.dashboard import bp as dashboard_bp
|
|
from routes.annonces import bp as annonces_bp
|
|
from routes.fichiers import bp as fichiers_bp
|
|
from routes.evenements import bp as evenements_bp
|
|
from routes.rgpd import bp as rgpd_bp
|
|
|
|
app.register_blueprint(init_auth_routes(oauth))
|
|
app.register_blueprint(dashboard_bp)
|
|
app.register_blueprint(annonces_bp)
|
|
app.register_blueprint(fichiers_bp)
|
|
app.register_blueprint(evenements_bp)
|
|
app.register_blueprint(rgpd_bp)
|
|
|
|
register_error_handlers(app)
|
|
return app
|
|
|
|
|
|
def register_error_handlers(app):
|
|
"""Gestionnaires d'erreurs globaux (Bloc 1 - C5) : réponses uniformisées,
|
|
aucune fuite d'information système sensible (stack trace, chemin serveur...).
|
|
"""
|
|
|
|
@app.errorhandler(403)
|
|
def forbidden(_error):
|
|
if _wants_json():
|
|
return jsonify({"error": "forbidden"}), 403
|
|
return render_template("errors/403.html"), 403
|
|
|
|
@app.errorhandler(404)
|
|
def not_found(_error):
|
|
if _wants_json():
|
|
return jsonify({"error": "not_found"}), 404
|
|
return render_template("errors/404.html"), 404
|
|
|
|
@app.errorhandler(500)
|
|
def server_error(error):
|
|
app.logger.exception("Erreur interne non gérée: %s", error)
|
|
if _wants_json():
|
|
return jsonify({"error": "internal_error"}), 500
|
|
return render_template("errors/500.html"), 500
|
|
|
|
|
|
def _wants_json():
|
|
from flask import request
|
|
|
|
return request.path.startswith("/api/")
|
|
|
|
|
|
app = create_app()
|
|
|
|
if __name__ == "__main__":
|
|
app.run(host="0.0.0.0", port=5000, debug=Config.DEBUG)
|