1
0
forked from ScoDoc/ScoDoc

Table utilisateurs: affiche date approx. de dernière connexion même si pas SuperAdmin. Option éclater rôles.

This commit is contained in:
Emmanuel Viennet 2024-09-05 18:13:04 +02:00
parent bed5cc2c0c
commit 415e37ab67
2 changed files with 85 additions and 35 deletions

View File

@ -29,6 +29,7 @@
"""
# Anciennement ZScoUsers.py, fonctions de gestion des données réécrites avec flask/SQLAlchemy
import datetime
import re
from flask import url_for, g, render_template, request
@ -47,7 +48,11 @@ from app.scodoc.sco_exceptions import ScoValueError
def index_html(
all_depts=False, having_role_name: str = "", with_inactives=False, fmt="html"
all_depts=False,
having_role_name: str = "",
with_inactives=False,
detail_roles=False,
fmt="html",
):
"gestion utilisateurs..."
all_depts = int(all_depts)
@ -73,14 +78,6 @@ def index_html(
"""   Pour importer des utilisateurs en masse (via fichier xlsx)
contactez votre administrateur scodoc."""
)
if all_depts:
checked = "checked"
else:
checked = ""
if with_inactives:
olds_checked = "checked"
else:
olds_checked = ""
menu_roles = "\n".join(
f"""<option value="{r.name}" {
@ -92,9 +89,11 @@ def index_html(
f"""
<form name="f" action="{request.base_url}" method="get">
<input type="checkbox" name="all_depts" value="1" onchange="document.f.submit();"
{checked}>Tous les départements</input>
{"checked" if all_depts else ""}>Tous les départements</input>
<input type="checkbox" name="with_inactives" value="1" onchange="document.f.submit();"
{olds_checked}>Avec anciens utilisateurs</input>
{"checked" if with_inactives else ""}>Avec anciens utilisateurs</input>
<input type="checkbox" name="detail_roles" value="1" onchange="document.f.submit();"
{"checked" if detail_roles else ""}>Sépare les rôles</input>
<label for="having_role_name" style="margin-left:16px;">Filtrer par rôle:</label>
<select id="having_role_name" name="having_role_name" onchange="document.f.submit();">
@ -119,6 +118,7 @@ def index_html(
having_role=having_role,
with_inactives=with_inactives,
with_links=current_user.has_permission(Permission.UsersAdmin, g.scodoc_dept),
detail_roles=detail_roles,
)
if fmt != "html":
return content
@ -137,10 +137,12 @@ def list_users(
having_role: Role = None,
with_inactives=False,
with_links=True,
detail_roles=False,
):
"""List users, returns a table in the specified format.
Si with_inactives, inclut les anciens utilisateurs (status "old").
Si having_role, ne liste que les utilisateurs ayant ce rôle.
Si detail_roles, affiche les rôles dans des colonnes séparées.
"""
from app.scodoc.sco_permissions_check import can_handle_passwd
@ -179,9 +181,24 @@ def list_users(
d["non_migre"] = (
"NON MIGRÉ" if u.passwd_temp or u.password_scodoc7 else "ok"
)
if not current_user.is_administrator():
# si non super-admin, ne donne pas la date exacte de derniere connexion
d["last_seen"] = _approximate_date(u.last_seen)
else:
d["date_modif_passwd"] = "(non visible)"
d["non_migre"] = ""
if detail_roles:
d["roles_set"] = {
f"{r.role.name or ''}_{r.dept or ''}" for r in u.user_roles
}
if detail_roles:
roles_set = set()
for d in rows:
roles_set.update(d["roles_set"])
roles_columns = sorted(roles_set)
for d in rows:
d.update({r: "X" if r in d["roles_set"] else "" for r in roles_columns})
columns_ids = [
"user_name",
@ -206,31 +223,39 @@ def list_users(
"cas_allow_scodoc_login",
"cas_last_login",
]
columns_ids += ["email_institutionnel", "edt_id"]
elif can_modify:
# Si l'utilisateur est admin local (can_modify) mais pas super admin,
# indique une date de dernière connexion approchée (mois, année)
columns_ids.append("last_seen")
columns_ids += ["email_institutionnel", "edt_id"]
title = "Utilisateurs définis dans ScoDoc"
titles = {
"user_name": "Login",
"nom_fmt": "Nom",
"prenom_fmt": "Prénom",
"email": "Mail",
"email_institutionnel": "Mail institutionnel (opt.)",
"dept": "Dept.",
"roles_string": "Rôles",
"date_expiration": "Expiration",
"date_modif_passwd": "Modif. mot de passe",
"last_seen": "Dernière cnx.",
"non_migre": "Non migré (!)",
"status_txt": "Etat",
"cas_id": "Id CAS",
"cas_allow_login": "CAS autorisé",
"cas_allow_scodoc_login": "Cnx sans CAS",
"cas_last_login": "Dernier login CAS",
"edt_id": "Identifiant emploi du temps",
}
if detail_roles:
columns_ids += roles_columns
titles.update({r: r for r in roles_columns})
tab = GenTable(
rows=rows,
columns_ids=columns_ids,
titles={
"user_name": "Login",
"nom_fmt": "Nom",
"prenom_fmt": "Prénom",
"email": "Mail",
"email_institutionnel": "Mail institutionnel (opt.)",
"dept": "Dept.",
"roles_string": "Rôles",
"date_expiration": "Expiration",
"date_modif_passwd": "Modif. mot de passe",
"last_seen": "Dernière cnx.",
"non_migre": "Non migré (!)",
"status_txt": "Etat",
"cas_id": "Id CAS",
"cas_allow_login": "CAS autorisé",
"cas_allow_scodoc_login": "Cnx sans CAS",
"cas_last_login": "Dernier login CAS",
"edt_id": "Identifiant emploi du temps",
},
titles=titles,
caption=title,
page_title="title",
html_title=f"""<h2>{len(rows)} utilisateurs {comm}</h2>
@ -247,6 +272,28 @@ def list_users(
return tab.make_page(fmt=fmt, with_html_headers=False)
def _approximate_date(date: datetime.datetime) -> str:
if not date:
return "jamais vu"
now = datetime.datetime.now()
# Calculate the difference in years and months
delta_years = now.year - date.year
delta_months = now.month - date.month
if delta_years == 0 and delta_months == 0:
return "ce mois"
if delta_years == 0 or (delta_years == 1 and delta_months < 0):
return "cette année"
if delta_years == 1:
return "l'an dernier"
if delta_years == 2:
return "il y a 2 ans"
return "pas vu depuis très lontemps"
def get_users_count(dept=None) -> int:
"""Nombre de comptes utilisateurs, tout état confondu, dans ce dept
(ou dans tous si None)"""

View File

@ -135,13 +135,16 @@ class Mode(IntEnum):
@bp.route("/index_html", alias=True)
@scodoc
@permission_required(Permission.UsersView)
@scodoc7func
def index_html(
all_depts=False, having_role_name: str = "", with_inactives=False, fmt="html"
):
def index_html():
"Page accueil utilisateur: tableau avec liste des comptes"
all_depts = scu.to_bool(request.args.get("all_depts", False))
detail_roles = scu.to_bool(request.args.get("detail_roles", False))
fmt = request.args.get("fmt", "html")
having_role_name = request.args.get("having_role_name", "")
with_inactives = scu.to_bool(request.args.get("with_inactives", False))
return sco_users.index_html(
all_depts=all_depts,
detail_roles=detail_roles,
having_role_name=having_role_name,
with_inactives=with_inactives,
fmt=fmt,