Table utilisateurs: affiche date approx. de dernière connexion même si pas SuperAdmin. Option éclater rôles.
This commit is contained in:
parent
bed5cc2c0c
commit
415e37ab67
@ -29,6 +29,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Anciennement ZScoUsers.py, fonctions de gestion des données réécrites avec flask/SQLAlchemy
|
# Anciennement ZScoUsers.py, fonctions de gestion des données réécrites avec flask/SQLAlchemy
|
||||||
|
import datetime
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from flask import url_for, g, render_template, request
|
from flask import url_for, g, render_template, request
|
||||||
@ -47,7 +48,11 @@ from app.scodoc.sco_exceptions import ScoValueError
|
|||||||
|
|
||||||
|
|
||||||
def index_html(
|
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..."
|
"gestion utilisateurs..."
|
||||||
all_depts = int(all_depts)
|
all_depts = int(all_depts)
|
||||||
@ -73,14 +78,6 @@ def index_html(
|
|||||||
""" Pour importer des utilisateurs en masse (via fichier xlsx)
|
""" Pour importer des utilisateurs en masse (via fichier xlsx)
|
||||||
contactez votre administrateur scodoc."""
|
contactez votre administrateur scodoc."""
|
||||||
)
|
)
|
||||||
if all_depts:
|
|
||||||
checked = "checked"
|
|
||||||
else:
|
|
||||||
checked = ""
|
|
||||||
if with_inactives:
|
|
||||||
olds_checked = "checked"
|
|
||||||
else:
|
|
||||||
olds_checked = ""
|
|
||||||
|
|
||||||
menu_roles = "\n".join(
|
menu_roles = "\n".join(
|
||||||
f"""<option value="{r.name}" {
|
f"""<option value="{r.name}" {
|
||||||
@ -92,9 +89,11 @@ def index_html(
|
|||||||
f"""
|
f"""
|
||||||
<form name="f" action="{request.base_url}" method="get">
|
<form name="f" action="{request.base_url}" method="get">
|
||||||
<input type="checkbox" name="all_depts" value="1" onchange="document.f.submit();"
|
<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();"
|
<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>
|
<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();">
|
<select id="having_role_name" name="having_role_name" onchange="document.f.submit();">
|
||||||
@ -119,6 +118,7 @@ def index_html(
|
|||||||
having_role=having_role,
|
having_role=having_role,
|
||||||
with_inactives=with_inactives,
|
with_inactives=with_inactives,
|
||||||
with_links=current_user.has_permission(Permission.UsersAdmin, g.scodoc_dept),
|
with_links=current_user.has_permission(Permission.UsersAdmin, g.scodoc_dept),
|
||||||
|
detail_roles=detail_roles,
|
||||||
)
|
)
|
||||||
if fmt != "html":
|
if fmt != "html":
|
||||||
return content
|
return content
|
||||||
@ -137,10 +137,12 @@ def list_users(
|
|||||||
having_role: Role = None,
|
having_role: Role = None,
|
||||||
with_inactives=False,
|
with_inactives=False,
|
||||||
with_links=True,
|
with_links=True,
|
||||||
|
detail_roles=False,
|
||||||
):
|
):
|
||||||
"""List users, returns a table in the specified format.
|
"""List users, returns a table in the specified format.
|
||||||
Si with_inactives, inclut les anciens utilisateurs (status "old").
|
Si with_inactives, inclut les anciens utilisateurs (status "old").
|
||||||
Si having_role, ne liste que les utilisateurs ayant ce rôle.
|
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
|
from app.scodoc.sco_permissions_check import can_handle_passwd
|
||||||
|
|
||||||
@ -179,9 +181,24 @@ def list_users(
|
|||||||
d["non_migre"] = (
|
d["non_migre"] = (
|
||||||
"NON MIGRÉ" if u.passwd_temp or u.password_scodoc7 else "ok"
|
"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:
|
else:
|
||||||
d["date_modif_passwd"] = "(non visible)"
|
d["date_modif_passwd"] = "(non visible)"
|
||||||
d["non_migre"] = ""
|
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 = [
|
columns_ids = [
|
||||||
"user_name",
|
"user_name",
|
||||||
@ -206,13 +223,14 @@ def list_users(
|
|||||||
"cas_allow_scodoc_login",
|
"cas_allow_scodoc_login",
|
||||||
"cas_last_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"
|
title = "Utilisateurs définis dans ScoDoc"
|
||||||
tab = GenTable(
|
titles = {
|
||||||
rows=rows,
|
|
||||||
columns_ids=columns_ids,
|
|
||||||
titles={
|
|
||||||
"user_name": "Login",
|
"user_name": "Login",
|
||||||
"nom_fmt": "Nom",
|
"nom_fmt": "Nom",
|
||||||
"prenom_fmt": "Prénom",
|
"prenom_fmt": "Prénom",
|
||||||
@ -230,7 +248,14 @@ def list_users(
|
|||||||
"cas_allow_scodoc_login": "Cnx sans CAS",
|
"cas_allow_scodoc_login": "Cnx sans CAS",
|
||||||
"cas_last_login": "Dernier login CAS",
|
"cas_last_login": "Dernier login CAS",
|
||||||
"edt_id": "Identifiant emploi du temps",
|
"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=titles,
|
||||||
caption=title,
|
caption=title,
|
||||||
page_title="title",
|
page_title="title",
|
||||||
html_title=f"""<h2>{len(rows)} utilisateurs {comm}</h2>
|
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)
|
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:
|
def get_users_count(dept=None) -> int:
|
||||||
"""Nombre de comptes utilisateurs, tout état confondu, dans ce dept
|
"""Nombre de comptes utilisateurs, tout état confondu, dans ce dept
|
||||||
(ou dans tous si None)"""
|
(ou dans tous si None)"""
|
||||||
|
@ -135,13 +135,16 @@ class Mode(IntEnum):
|
|||||||
@bp.route("/index_html", alias=True)
|
@bp.route("/index_html", alias=True)
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.UsersView)
|
@permission_required(Permission.UsersView)
|
||||||
@scodoc7func
|
def index_html():
|
||||||
def index_html(
|
|
||||||
all_depts=False, having_role_name: str = "", with_inactives=False, fmt="html"
|
|
||||||
):
|
|
||||||
"Page accueil utilisateur: tableau avec liste des comptes"
|
"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(
|
return sco_users.index_html(
|
||||||
all_depts=all_depts,
|
all_depts=all_depts,
|
||||||
|
detail_roles=detail_roles,
|
||||||
having_role_name=having_role_name,
|
having_role_name=having_role_name,
|
||||||
with_inactives=with_inactives,
|
with_inactives=with_inactives,
|
||||||
fmt=fmt,
|
fmt=fmt,
|
||||||
|
Loading…
Reference in New Issue
Block a user