CAS: Améliore traitement des erreurs

This commit is contained in:
Emmanuel Viennet 2023-02-27 09:46:15 +01:00
parent a34702d247
commit dd6ca9b188
4 changed files with 20 additions and 13 deletions

View File

@ -231,12 +231,11 @@ def create_app(config_class=DevConfig):
CAS(app, url_prefix="/cas") CAS(app, url_prefix="/cas")
app.wsgi_app = ReverseProxied(app.wsgi_app) app.wsgi_app = ReverseProxied(app.wsgi_app)
app.json_encoder = ScoDocJSONEncoder 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) 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 # Vérifie/crée lien sym pour les URL statiques
link_filename = f"{app.root_path}/static/links/{sco_version.SCOVERSION}" link_filename = f"{app.root_path}/static/links/{sco_version.SCOVERSION}"

View File

@ -11,6 +11,7 @@ from flask_login import login_user
from app.auth import bp from app.auth import bp
from app.auth.models import User from app.auth.models import User
from app.models.config import ScoDocSiteConfig 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. # 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")) 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): def set_cas_configuration(app: flask.app.Flask = None):
"""Force la configuration du module flask_cas à partir des paramètres de """Force la configuration du module flask_cas à partir des paramètres de
la config de ScoDoc. 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_SERVER"] = ScoDocSiteConfig.get("cas_server")
app.config["CAS_AFTER_LOGIN"] = "auth.after_cas_login" app.config["CAS_AFTER_LOGIN"] = "auth.after_cas_login"
app.config["CAS_AFTER_LOGOUT"] = "auth.after_cas_logout" 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_VERIFY"] = ScoDocSiteConfig.get("cas_ssl_verify")
app.config["CAS_SSL_CERTIFICATE"] = ScoDocSiteConfig.get("cas_ssl_certificate") app.config["CAS_SSL_CERTIFICATE"] = ScoDocSiteConfig.get("cas_ssl_certificate")
else: else:

View File

@ -1,7 +1,7 @@
# -*- coding: UTF-8 -* # -*- coding: UTF-8 -*
import os import os
import uuid import logging
from dotenv import load_dotenv from dotenv import load_dotenv
BASEDIR = os.path.abspath(os.path.dirname(__file__)) BASEDIR = os.path.abspath(os.path.dirname(__file__))
@ -16,6 +16,7 @@ class Config:
SECRET_KEY = os.environ.get("SECRET_KEY") or "90e01e75831e4276a4c70d29564b425f" SECRET_KEY = os.environ.get("SECRET_KEY") or "90e01e75831e4276a4c70d29564b425f"
SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_TRACK_MODIFICATIONS = False
LOG_TO_STDOUT = os.environ.get("LOG_TO_STDOUT") 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_SERVER = os.environ.get("MAIL_SERVER", "localhost")
MAIL_PORT = int(os.environ.get("MAIL_PORT", 25)) MAIL_PORT = int(os.environ.get("MAIL_PORT", 25))
MAIL_USE_TLS = os.environ.get("MAIL_USE_TLS") is not None 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: # Pour conserver l'ordre des objets dans les JSON:
# e.g. l'ordre des UE dans les bulletins # e.g. l'ordre des UE dans les bulletins
JSON_SORT_KEYS = False 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): class ProdConfig(Config):

View File

@ -113,7 +113,7 @@ def validate(ticket):
cas_username_session_key = current_app.config["CAS_USERNAME_SESSION_KEY"] cas_username_session_key = current_app.config["CAS_USERNAME_SESSION_KEY"]
cas_attributes_session_key = current_app.config["CAS_ATTRIBUTES_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)) current_app.logger.debug("validating token {0}".format(ticket))
cas_validate_url = create_cas_validate_url( cas_validate_url = create_cas_validate_url(
@ -140,6 +140,8 @@ def validate(ticket):
ssl_context.load_verify_locations(cadata=ca_data) ssl_context.load_verify_locations(cadata=ca_data)
except (ssl.SSLError, ValueError): except (ssl.SSLError, ValueError):
current_app.logger.error("CAS : error loading SSL cert.") current_app.logger.error("CAS : error loading SSL cert.")
if cas_error_callback:
cas_error_callback("erreur chargement certificat SSL CAS (PEM)")
return False return False
else: else:
ssl_context = None ssl_context = None
@ -159,8 +161,13 @@ def validate(ticket):
) )
except ValueError: except ValueError:
current_app.logger.error("CAS returned unexpected result") current_app.logger.error("CAS returned unexpected result")
if cas_error_callback:
cas_error_callback("réponse invalide du serveur CAS")
except URLError: except URLError:
current_app.logger.error("CAS : error validating token: check SSL certificate") 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: if isValid:
current_app.logger.debug("valid") current_app.logger.debug("valid")