forked from ScoDoc/ScoDoc
Emmanuel Viennet
0c0d43d075
- enregistre date derniere connection. - nouvelle permission: ScoUsersChangeCASId - améliore affichage infos utilisateur.
97 lines
3.6 KiB
Python
97 lines
3.6 KiB
Python
# -*- coding: UTF-8 -*
|
|
"""
|
|
auth.cas.py
|
|
"""
|
|
import datetime
|
|
|
|
import flask
|
|
from flask import current_app, flash, url_for
|
|
from flask_login import login_user
|
|
|
|
from app import db
|
|
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.
|
|
|
|
|
|
@bp.route("/after_cas_login")
|
|
def after_cas_login():
|
|
"Called by CAS after CAS authentication"
|
|
# Ici on a les infos dans flask.session["CAS_ATTRIBUTES"]
|
|
if ScoDocSiteConfig.is_cas_enabled() and ("CAS_ATTRIBUTES" in flask.session):
|
|
# Lookup user:
|
|
cas_id = flask.session["CAS_ATTRIBUTES"].get(
|
|
"cas:" + ScoDocSiteConfig.get("cas_attribute_id"),
|
|
flask.session.get("CAS_USERNAME"),
|
|
)
|
|
if cas_id is not None:
|
|
user: User = User.query.filter_by(cas_id=cas_id).first()
|
|
if user and user.active:
|
|
if user.cas_allow_login:
|
|
current_app.logger.info(f"CAS: login {user.user_name}")
|
|
if login_user(user):
|
|
flask.session[
|
|
"scodoc_cas_login_date"
|
|
] = datetime.datetime.now().isoformat()
|
|
user.cas_last_login = datetime.datetime.utcnow()
|
|
db.session.add(user)
|
|
db.session.commit()
|
|
return flask.redirect(url_for("scodoc.index"))
|
|
else:
|
|
current_app.logger.info(
|
|
f"CAS login denied for {user.user_name} (not allowed to use CAS)"
|
|
)
|
|
else:
|
|
current_app.logger.info(
|
|
f"""CAS login denied for {
|
|
user.user_name if user else ""
|
|
} cas_id={cas_id} (unknown or inactive)"""
|
|
)
|
|
else:
|
|
current_app.logger.info(
|
|
f"""CAS attribute '{ScoDocSiteConfig.get("cas_attribute_id")}' not found !
|
|
(check your ScoDoc config)"""
|
|
)
|
|
|
|
# Echec:
|
|
flash("échec de l'authentification")
|
|
return flask.redirect(url_for("auth.login"))
|
|
|
|
|
|
@bp.route("/after_cas_logout")
|
|
def after_cas_logout():
|
|
"Called by CAS after CAS logout"
|
|
flash("Vous êtes déconnecté")
|
|
current_app.logger.info("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.
|
|
Appelé au démarrage et à chaque modif des paramètres.
|
|
"""
|
|
app = app or current_app
|
|
if ScoDocSiteConfig.is_cas_enabled():
|
|
current_app.logger.debug("CAS: set_cas_configuration")
|
|
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:
|
|
app.config.pop("CAS_SERVER", None)
|
|
app.config.pop("CAS_AFTER_LOGIN", None)
|
|
app.config.pop("CAS_AFTER_LOGOUT", None)
|
|
app.config.pop("CAS_SSL_VERIFY", None)
|
|
app.config.pop("CAS_SSL_CERTIFICATE", None)
|