forked from ScoDoc/ScoDoc
CAS:
- enregistre date derniere connection. - nouvelle permission: ScoUsersChangeCASId - améliore affichage infos utilisateur.
This commit is contained in:
parent
be76fc8f42
commit
9c2c8d9047
@ -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"
|
||||
|
@ -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 "<UserRole u={} r={} dept={}>".format(self.user, self.role, self.dept)
|
||||
return f"<UserRole u={self.user} r={self.role} dept={self.dept}>"
|
||||
|
||||
@staticmethod
|
||||
def role_dept_from_string(role_dept: str):
|
||||
|
@ -225,7 +225,6 @@ _identiteEditor = ndb.EditableTable(
|
||||
"nom",
|
||||
"nom_usuel",
|
||||
"prenom",
|
||||
"cas_id",
|
||||
"civilite", # 'M", "F", or "X"
|
||||
"date_naissance",
|
||||
"lieu_naissance",
|
||||
|
@ -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,7 +54,8 @@ _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"),
|
||||
(1 << 40, "ScoAssiduiteChange", "Modifier les assiduités"),
|
||||
(1 << 41, "ScoJustifChange", "Modifier les justificatifs"),
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -4,8 +4,9 @@
|
||||
|
||||
{% block app_content %}
|
||||
|
||||
<div class="user_info">
|
||||
<h2>Utilisateur: {{user.user_name}} ({{'actif' if user.active else 'fermé'}})</h2>
|
||||
<p>
|
||||
<div class="user_basics">
|
||||
<b>Login :</b> {{user.user_name}}<br>
|
||||
<b>CAS id:</b> {{user.cas_id or "(aucun)"}}
|
||||
(CAS {{'autorisé' if user.cas_allow_login else 'interdit'}} pour cet utilisateur)
|
||||
@ -17,12 +18,22 @@
|
||||
<b>Prénom :</b> {{user.prenom or ""}}<br>
|
||||
<b>Mail :</b> {{user.email}}<br>
|
||||
<b>Roles :</b> {{user.get_roles_string()}}<br>
|
||||
<b>Dept :</b> {{user.dept or ""}}<br>
|
||||
<b>Dept :</b> {{user.dept or ""}}
|
||||
</div>
|
||||
{% if current_user.is_administrator() %}
|
||||
<div class="user_info_admin">
|
||||
<b>Dernière vue :</b> {{user.last_seen or "-"}}<br>
|
||||
<b>Dernière connexion CAS :</b> {{user.cas_last_login or "-"}}<br>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="user_basics">
|
||||
<b>Dernière modif mot de passe:</b>
|
||||
{{user.date_modif_passwd.isoformat() if user.date_modif_passwd else ""}}<br>
|
||||
<b>Date d'expiration:</b>
|
||||
{{user.date_expiration.isoformat() if user.date_expiration else "(sans limite)"}}
|
||||
<p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ul>
|
||||
{% if (
|
||||
current_user.is_administrator()
|
||||
@ -52,6 +63,7 @@
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{% if current_user.id == user.id %}
|
||||
<div class="user_info_session">
|
||||
@ -71,9 +83,9 @@
|
||||
<ul>
|
||||
{% for p in Permission.description %}
|
||||
<li>{{Permission.description[p]}} :
|
||||
{{
|
||||
<b>{{
|
||||
"oui" if user.has_permission(Permission.get_by_name(p), dept) else "non"
|
||||
}}
|
||||
}}</b>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
@ -84,6 +96,7 @@
|
||||
{{url_for('users.index_html', scodoc_dept=g.scodoc_dept)}}
|
||||
">Liste de tous les utilisateurs</a></p>
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
@ -395,7 +395,8 @@ def create_user_form(user_name=None, edit=0, all_roles=True):
|
||||
else "(service CAS non activé)",
|
||||
"size": 36,
|
||||
"allow_null": True,
|
||||
"readonly": not cas_enabled,
|
||||
"readonly": not cas_enabled
|
||||
or not current_user.has_permission(Permission.ScoUsersChangeCASId),
|
||||
},
|
||||
),
|
||||
(
|
||||
@ -403,8 +404,9 @@ def create_user_form(user_name=None, edit=0, all_roles=True):
|
||||
{
|
||||
"title": "Autorise connexion via CAS",
|
||||
"input_type": "boolcheckbox",
|
||||
"explanation": " seul le super-administrateur peut changer ce réglage",
|
||||
"readonly": not current_user.is_administrator(),
|
||||
"explanation": """ si CAS est activé.
|
||||
Seul le super-administrateur peut changer ce réglage.""",
|
||||
"enabled": current_user.is_administrator(),
|
||||
},
|
||||
),
|
||||
(
|
||||
@ -412,8 +414,9 @@ def create_user_form(user_name=None, edit=0, all_roles=True):
|
||||
{
|
||||
"title": "Autorise connexion via ScoDoc",
|
||||
"input_type": "boolcheckbox",
|
||||
"explanation": " seul le super-administrateur peut changer ce réglage",
|
||||
"readonly": not current_user.is_administrator(),
|
||||
"explanation": """ même si "Forcer l'utilisation de CAS" est activé.
|
||||
Seul le super-administrateur peut changer ce réglage""",
|
||||
"enabled": current_user.is_administrator(),
|
||||
},
|
||||
),
|
||||
]
|
||||
@ -552,6 +555,12 @@ def create_user_form(user_name=None, edit=0, all_roles=True):
|
||||
else:
|
||||
vals = tf[2]
|
||||
roles = set(vals["roles"]).intersection(editable_roles_strings)
|
||||
if not current_user.is_administrator():
|
||||
# empeche modification des paramètres CAS
|
||||
vals.pop("cas_allow_login", None)
|
||||
vals.pop("cas_allow_scodoc_login", None)
|
||||
if not current_user.has_permission(Permission.ScoUsersChangeCASId):
|
||||
vals.pop("cas_id", None)
|
||||
if "edit" in vals:
|
||||
edit = int(vals["edit"])
|
||||
else:
|
||||
|
28
migrations/versions/5731e904baac_cas_last_login.py
Normal file
28
migrations/versions/5731e904baac_cas_last_login.py
Normal file
@ -0,0 +1,28 @@
|
||||
"""CAS last login
|
||||
|
||||
Revision ID: 5731e904baac
|
||||
Revises: 4c19fcb42636
|
||||
Create Date: 2023-03-02 11:36:58.465579
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "5731e904baac"
|
||||
down_revision = "4c19fcb42636"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column("user", sa.Column("cas_last_login", sa.DateTime(), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column("user", "cas_last_login")
|
||||
# ### end Alembic commands ###
|
@ -1,7 +1,7 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
SCOVERSION = "9.4.58"
|
||||
SCOVERSION = "9.4.59"
|
||||
|
||||
SCONAME = "ScoDoc"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user