From dd6ca9b188aab3006fefe13d87cdc03e5d5f2e63 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Mon, 27 Feb 2023 09:46:15 +0100 Subject: [PATCH] =?UTF-8?q?CAS:=20Am=C3=A9liore=20traitement=20des=20erreu?= =?UTF-8?q?rs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/__init__.py | 7 +++---- app/auth/cas.py | 7 +++++++ config.py | 10 ++-------- flask_cas/routing.py | 9 ++++++++- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index a1edfbd7bb..856dd8ea58 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -231,12 +231,11 @@ def create_app(config_class=DevConfig): CAS(app, url_prefix="/cas") app.wsgi_app = ReverseProxied(app.wsgi_app) app.json_encoder = ScoDocJSONEncoder - app.logger.setLevel(logging.INFO) - - # Evite de logguer toutes les requetes dans notre log - logging.getLogger("werkzeug").disabled = True app.config.from_object(config_class) + # Evite de logguer toutes les requetes dans notre log + logging.getLogger("werkzeug").disabled = True + app.logger.setLevel(app.config["LOG_LEVEL"]) # Vérifie/crée lien sym pour les URL statiques link_filename = f"{app.root_path}/static/links/{sco_version.SCOVERSION}" diff --git a/app/auth/cas.py b/app/auth/cas.py index fece96a0fe..4b478eaf8c 100644 --- a/app/auth/cas.py +++ b/app/auth/cas.py @@ -11,6 +11,7 @@ from flask_login import login_user from app.auth import bp from app.auth.models import User from app.models.config import ScoDocSiteConfig +from app.scodoc.sco_exceptions import ScoValueError # after_cas_login/after_cas_logout : routes appelées par redirect depuis le serveur CAS. @@ -61,6 +62,11 @@ def after_cas_logout(): return flask.redirect(url_for("scodoc.index")) +def cas_error_callback(message): + "Called by CAS when an error occurs, with a message" + raise ScoValueError(f"Erreur authentification CAS: {message}") + + def set_cas_configuration(app: flask.app.Flask = None): """Force la configuration du module flask_cas à partir des paramètres de la config de ScoDoc. @@ -71,6 +77,7 @@ def set_cas_configuration(app: flask.app.Flask = None): app.config["CAS_SERVER"] = ScoDocSiteConfig.get("cas_server") app.config["CAS_AFTER_LOGIN"] = "auth.after_cas_login" app.config["CAS_AFTER_LOGOUT"] = "auth.after_cas_logout" + app.config["CAS_ERROR_CALLBACK"] = cas_error_callback app.config["CAS_SSL_VERIFY"] = ScoDocSiteConfig.get("cas_ssl_verify") app.config["CAS_SSL_CERTIFICATE"] = ScoDocSiteConfig.get("cas_ssl_certificate") else: diff --git a/config.py b/config.py index 584a6843b6..ed456b0b2c 100755 --- a/config.py +++ b/config.py @@ -1,7 +1,7 @@ # -*- coding: UTF-8 -* import os -import uuid +import logging from dotenv import load_dotenv BASEDIR = os.path.abspath(os.path.dirname(__file__)) @@ -16,6 +16,7 @@ class Config: SECRET_KEY = os.environ.get("SECRET_KEY") or "90e01e75831e4276a4c70d29564b425f" SQLALCHEMY_TRACK_MODIFICATIONS = False LOG_TO_STDOUT = os.environ.get("LOG_TO_STDOUT") + LOG_LEVEL = getattr(logging, os.environ.get("LOG_LEVEL", "INFO"), "INFO") MAIL_SERVER = os.environ.get("MAIL_SERVER", "localhost") MAIL_PORT = int(os.environ.get("MAIL_PORT", 25)) MAIL_USE_TLS = os.environ.get("MAIL_USE_TLS") is not None @@ -40,13 +41,6 @@ class Config: # Pour conserver l'ordre des objets dans les JSON: # e.g. l'ordre des UE dans les bulletins JSON_SORT_KEYS = False - # STATIC_URL_PATH = "/ScoDoc/static" - # static_folder = "stat" - # SERVER_NAME = os.environ.get("SERVER_NAME") - # XXX temporaire: utiliser SiteConfig - CAS_SERVER = os.environ.get("CAS_SERVER") - CAS_AFTER_LOGIN = os.environ.get("CAS_AFTER_LOGIN") - CAS_AFTER_LOGOUT = os.environ.get("CAS_AFTER_LOGOUT") class ProdConfig(Config): diff --git a/flask_cas/routing.py b/flask_cas/routing.py index c6e4dfe8a3..40112057d3 100644 --- a/flask_cas/routing.py +++ b/flask_cas/routing.py @@ -113,7 +113,7 @@ def validate(ticket): cas_username_session_key = current_app.config["CAS_USERNAME_SESSION_KEY"] cas_attributes_session_key = current_app.config["CAS_ATTRIBUTES_SESSION_KEY"] - + cas_error_callback = current_app.config.get("CAS_ERROR_CALLBACK") current_app.logger.debug("validating token {0}".format(ticket)) cas_validate_url = create_cas_validate_url( @@ -140,6 +140,8 @@ def validate(ticket): ssl_context.load_verify_locations(cadata=ca_data) except (ssl.SSLError, ValueError): current_app.logger.error("CAS : error loading SSL cert.") + if cas_error_callback: + cas_error_callback("erreur chargement certificat SSL CAS (PEM)") return False else: ssl_context = None @@ -159,8 +161,13 @@ def validate(ticket): ) except ValueError: current_app.logger.error("CAS returned unexpected result") + if cas_error_callback: + cas_error_callback("réponse invalide du serveur CAS") except URLError: current_app.logger.error("CAS : error validating token: check SSL certificate") + cas_error_callback( + "erreur connexion au serveur CAS: vérifiez le certificat SSL" + ) if isValid: current_app.logger.debug("valid")