From 0c0d43d07560c55995fa8287dc6afda0ad97b416 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Thu, 2 Mar 2023 14:49:18 +0100 Subject: [PATCH] =?UTF-8?q?CAS:=20=20-=20enregistre=20date=20derniere=20co?= =?UTF-8?q?nnection.=20=20-=20nouvelle=20permission:=20ScoUsersChangeCASId?= =?UTF-8?q?=20=20-=20am=C3=A9liore=20affichage=20infos=20utilisateur.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/auth/cas.py | 8 ++++-- app/auth/models.py | 9 ++++-- app/scodoc/sco_etud.py | 1 - app/scodoc/sco_permissions.py | 7 +++-- app/scodoc/sco_users.py | 9 +++++- app/static/css/scodoc.css | 25 +++++++++++++++++ app/templates/auth/user_info_page.j2 | 23 +++++++++++---- app/views/users.py | 19 +++++++++---- .../versions/5731e904baac_cas_last_login.py | 28 +++++++++++++++++++ sco_version.py | 2 +- 10 files changed, 112 insertions(+), 19 deletions(-) create mode 100644 migrations/versions/5731e904baac_cas_last_login.py diff --git a/app/auth/cas.py b/app/auth/cas.py index 469617298a..f47641f19d 100644 --- a/app/auth/cas.py +++ b/app/auth/cas.py @@ -8,6 +8,7 @@ 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 @@ -27,7 +28,7 @@ def after_cas_login(): flask.session.get("CAS_USERNAME"), ) if cas_id is not None: - user = User.query.filter_by(cas_id=cas_id).first() + 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}") @@ -35,6 +36,9 @@ def after_cas_login(): 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( @@ -77,7 +81,7 @@ def set_cas_configuration(app: flask.app.Flask = None): """ app = app or current_app if ScoDocSiteConfig.is_cas_enabled(): - current_app.logger.info("CAS: set_cas_configuration") + 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" diff --git a/app/auth/models.py b/app/auth/models.py index e8e1be50b2..310589afb2 100644 --- a/app/auth/models.py +++ b/app/auth/models.py @@ -75,6 +75,8 @@ class User(UserMixin, db.Model): """Si CAS forcé (cas_force), peut-on se logguer sur ScoDoc directement ? (le rôle ScoSuperAdmin peut toujours, mettre à True pour les utilisateur API) """ + cas_last_login = db.Column(db.DateTime, nullable=True) + """date du dernier login via CAS""" password_hash = db.Column(db.String(128)) password_scodoc7 = db.Column(db.String(42)) @@ -212,6 +214,9 @@ class User(UserMixin, db.Model): "cas_id": self.cas_id, "cas_allow_login": self.cas_allow_login, "cas_allow_scodoc_login": self.cas_allow_scodoc_login, + "cas_last_login": self.cas_last_login.isoformat() + "Z" + if self.cas_last_login + else None, "status_txt": "actif" if self.active else "fermé", "last_seen": self.last_seen.isoformat() + "Z" if self.last_seen else None, "nom": (self.nom or ""), # sco8 @@ -250,7 +255,7 @@ class User(UserMixin, db.Model): "cas_allow_login", "cas_allow_scodoc_login", ]: - setattr(self, field, data.get(field, False)) + setattr(self, field, scu.to_bool(data.get(field, False))) if new_user: if "user_name" in data: @@ -552,7 +557,7 @@ class UserRole(db.Model): ) def __repr__(self): - return "".format(self.user, self.role, self.dept) + return f"" @staticmethod def role_dept_from_string(role_dept: str): diff --git a/app/scodoc/sco_etud.py b/app/scodoc/sco_etud.py index 7ba017434c..3960286823 100644 --- a/app/scodoc/sco_etud.py +++ b/app/scodoc/sco_etud.py @@ -225,7 +225,6 @@ _identiteEditor = ndb.EditableTable( "nom", "nom_usuel", "prenom", - "cas_id", "civilite", # 'M", "F", or "X" "date_naissance", "lieu_naissance", diff --git a/app/scodoc/sco_permissions.py b/app/scodoc/sco_permissions.py index 78c6c10c6c..8c4edd8848 100644 --- a/app/scodoc/sco_permissions.py +++ b/app/scodoc/sco_permissions.py @@ -5,7 +5,8 @@ used by auth """ -# Définition des permissions: ne pas changer les numéros ou l'ordre des lignes ! +# Définition des permissions: NE PAS CHANGER les numéros ou l'ordre des lignes ! +# Les permissions sont sur un BigInt en base SQL, donc 64 bits. _SCO_PERMISSIONS = ( # permission bit, symbol, description # ScoSuperAdmin est utilisé pour: @@ -53,8 +54,10 @@ _SCO_PERMISSIONS = ( "RelationsEntreprisesExport", "Exporter les données de l'application relations entreprises", ), - # 27 à 39 ... réservé pour "entreprises" + (1 << 29, "ScoUsersChangeCASId", "Paramétrer l'id CAS"), + # (1 << 40, "ScoEtudChangePhoto", "Modifier la photo d'un étudiant"), + # Attention: les permissions sont codées sur 64 bits. ) diff --git a/app/scodoc/sco_users.py b/app/scodoc/sco_users.py index 7da03f29ce..16647f9aa0 100644 --- a/app/scodoc/sco_users.py +++ b/app/scodoc/sco_users.py @@ -162,7 +162,12 @@ def list_users( if current_user.is_administrator(): columns_ids.append("last_seen") if ScoDocSiteConfig.is_cas_enabled(): - columns_ids += ["cas_id", "cas_allow_login", "cas_allow_scodoc_login"] + columns_ids += [ + "cas_id", + "cas_allow_login", + "cas_allow_scodoc_login", + "cas_last_login", + ] title = "Utilisateurs définis dans ScoDoc" tab = GenTable( @@ -183,6 +188,7 @@ def list_users( "cas_id": "Id CAS", "cas_allow_login": "CAS autorisé", "cas_allow_scodoc_login": "Cnx sans CAS", + "cas_last_login": "Dernier login CAS", }, caption=title, page_title="title", @@ -276,6 +282,7 @@ def check_modif_user( ): """Vérifie que cet utilisateur peut être créé (edit=0) ou modifié (edit=1) Cherche homonymes. + Ne vérifie PAS que l'on a la permission de faire la modif. returns (ok, msg) - ok : si vrai, peut continuer avec ces parametres (si ok est faux, l'utilisateur peut quand même forcer la creation) diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css index 803855a5e2..f5c6c2fbfa 100644 --- a/app/static/css/scodoc.css +++ b/app/static/css/scodoc.css @@ -134,6 +134,31 @@ tr.bandeaugtr { color: rgb(255, 0, 0); } +div.user_info div { + padding: 8px; + border-radius: 16px; + margin-bottom: 8px; +} + +div.user_info ul li { + margin-bottom: 8px; +} + +div.user_basics { + border: 1px solid blue; + background-color: #eeeeee; +} + +div.user_info_admin { + border: 1px solid red; + background-color: #fdcaca; +} + +div.user_info div.permissions { + border: 1px solid rgb(0, 0, 255); + background-color: #dedefd; +} + /* ----- page content ------ */ div.about-logo { diff --git a/app/templates/auth/user_info_page.j2 b/app/templates/auth/user_info_page.j2 index 9adb97f235..80186d4d3d 100644 --- a/app/templates/auth/user_info_page.j2 +++ b/app/templates/auth/user_info_page.j2 @@ -4,8 +4,9 @@ {% block app_content %} +