diff --git a/app/views/users.py b/app/views/users.py
index 10f1124dd..315601bbd 100644
--- a/app/views/users.py
+++ b/app/views/users.py
@@ -41,8 +41,9 @@ from xml.etree import ElementTree
import flask
from flask import g, url_for, request, current_app, flash
from flask import redirect, render_template
-
from flask_login import current_user
+from flask_wtf import FlaskForm
+
from wtforms import HiddenField, PasswordField, StringField, SubmitField
from wtforms.validators import DataRequired, Email, ValidationError, EqualTo
@@ -62,7 +63,7 @@ from app.decorators import (
permission_required,
)
-from app.scodoc import html_sco_header, sco_import_users, sco_excel, sco_roles_default
+from app.scodoc import html_sco_header, sco_import_users, sco_roles_default
from app.scodoc import sco_users
from app.scodoc import sco_utils as scu
from app.scodoc import sco_xml
@@ -72,13 +73,14 @@ from app.scodoc.sco_import_users import generate_password
from app.scodoc.sco_permissions_check import can_handle_passwd
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
from app.views import users_bp as bp
-from flask_wtf import FlaskForm
_ = lambda x: x # sans babel
_l = _
class ChangePasswordForm(FlaskForm):
+ """formulaire changement mot de passe et mail"""
+
user_name = HiddenField()
old_password = PasswordField(_l("Identifiez-vous"))
new_password = PasswordField(_l("Nouveau mot de passe de l'utilisateur"))
@@ -102,6 +104,7 @@ class ChangePasswordForm(FlaskForm):
cancel = SubmitField("Annuler")
def validate_email(self, email):
+ "vérifie que le mail est unique"
user = User.query.filter_by(email=email.data.strip()).first()
if user is not None and self.user_name.data != user.user_name:
raise ValidationError(
@@ -109,8 +112,9 @@ class ChangePasswordForm(FlaskForm):
)
def validate_new_password(self, new_password):
+ "vérifie que le mot de passe est acceptable"
if new_password.data != "" and not is_valid_password(new_password.data):
- raise ValidationError(f"Mot de passe trop simple, recommencez")
+ raise ValidationError("Mot de passe trop simple, recommencez")
def validate_old_password(self, old_password):
if not current_user.check_password(old_password.data):
@@ -129,6 +133,7 @@ class Mode(IntEnum):
@permission_required(Permission.ScoUsersView)
@scodoc7func
def index_html(all_depts=False, with_inactives=False, format="html"):
+ "Page accueil utilisateur: tableau avec liste des comptes"
return sco_users.index_html(
all_depts=all_depts,
with_inactives=with_inactives,
@@ -136,15 +141,6 @@ def index_html(all_depts=False, with_inactives=False, format="html"):
)
-@bp.route("/user_info")
-@scodoc
-@permission_required(Permission.ScoUsersView)
-@scodoc7func
-def user_info(user_name, format="json"):
- info = sco_users.user_info(user_name)
- return scu.sendResult(info, name="user", format=format)
-
-
@bp.route("/create_user_form", methods=["GET", "POST"])
@scodoc
@permission_required(Permission.ScoUsersAdmin)
@@ -173,7 +169,7 @@ def create_user_form(user_name=None, edit=0, all_roles=False):
if not the_user:
raise ScoValueError("utilisateur inexistant")
initvalues = the_user.to_dict()
- H.append("
Modification de l'utilisateur %s
" % user_name)
+ H.append(f"Modification de l'utilisateur {user_name}
")
else:
H.append("Création d'un utilisateur
")
@@ -196,9 +192,9 @@ def create_user_form(user_name=None, edit=0, all_roles=False):
]
# Départements auxquels ont peut associer des rôles via ce dialogue:
# si SuperAdmin, tous les rôles standards dans tous les départements
- # sinon, les départements dans lesquels l'utilisateur a le droit
+ # sinon, les départements dans lesquels l'utilisateur a la permission ScoUsersAdmin
if is_super_admin:
- log("create_user_form called by %s (super admin)" % (current_user.user_name,))
+ log(f"create_user_form called by {current_user.user_name} (super admin)")
administrable_dept_acronyms = [d.acronym for d in Departement.query.all()]
else:
# Si on n'est pas SuperAdmin, liste les départements dans lesquels on a la
@@ -266,8 +262,8 @@ def create_user_form(user_name=None, edit=0, all_roles=False):
f"{dept or 'tout dépt.'}: {r.name}" for (r, dept) in displayed_roles
]
disabled_roles = {} # pour désactiver les roles que l'on ne peut pas éditer
- for i in range(len(displayed_roles_strings)):
- if displayed_roles_strings[i] not in editable_roles_strings:
+ for i, role_string in enumerate(displayed_roles_strings):
+ if role_string not in editable_roles_strings:
disabled_roles[i] = True
descr = [
("edit", {"input_type": "hidden", "default": edit}),
@@ -380,7 +376,7 @@ def create_user_form(user_name=None, edit=0, all_roles=False):
"input_type": "text",
"size": 12,
"allow_null": True,
- "explanation": """département de rattachement de l'utilisateur
+ "explanation": """département de rattachement de l'utilisateur
(s'il s'agit d'un administrateur, laisser vide si vous voulez
qu'il puisse créer des utilisateurs dans d'autres départements)
""",
@@ -418,8 +414,7 @@ def create_user_form(user_name=None, edit=0, all_roles=False):
"d",
{
"input_type": "separator",
- "title": "L'utilisateur appartient au département %s"
- % auth_dept,
+ "title": f"L'utilisateur appartient au département {auth_dept}",
},
)
)
@@ -429,8 +424,7 @@ def create_user_form(user_name=None, edit=0, all_roles=False):
"d",
{
"input_type": "separator",
- "title": "L'utilisateur sera crée dans le département %s"
- % auth_dept,
+ "title": f"L'utilisateur sera crée dans le département {auth_dept}",
},
)
)
@@ -469,7 +463,7 @@ def create_user_form(user_name=None, edit=0, all_roles=False):
),
]
vals = scu.get_request_args()
- if "tf_submitted" in vals and not "roles" in vals:
+ if "tf_submitted" in vals and "roles" not in vals:
vals["roles"] = []
if "tf_submitted" in vals:
# Ajoute roles existants mais non modifiables (disabled dans le form)
@@ -507,13 +501,15 @@ def create_user_form(user_name=None, edit=0, all_roles=False):
user_name = vals["user_name"]
# ce login existe ?
err = None
- users = sco_users._user_list(user_name)
- if edit and not users: # safety net, le user_name ne devrait pas changer
- err = "identifiant %s inexistant" % user_name
- if not edit and users:
- err = "identifiant %s déjà utilisé" % user_name
+ existing_user = User.query.filter_by(user_name=user_name)
+ if (
+ edit and existing_user is None
+ ): # safety net, le user_name ne devrait pas changer
+ err = f"identifiant {user_name} inexistant"
+ if not edit and existing_user is not None:
+ err = f"identifiant %{user_name} déjà utilisé"
if err:
- H.append(tf_error_message("""Erreur: %s""" % err))
+ H.append(tf_error_message(f"""Erreur: {err}"""))
return "\n".join(H) + "\n" + tf[1] + F
ok, msg = sco_users.check_modif_user(
edit,
@@ -570,15 +566,20 @@ def create_user_form(user_name=None, edit=0, all_roles=False):
vals["roles_string"] = ",".join(roles)
# ok, edit
- log("sco_users: editing %s by %s" % (user_name, current_user.user_name))
- log("sco_users: previous_values=%s" % initvalues)
- log("sco_users: new_values=%s" % vals)
+ log(f"sco_users: editing {user_name} by {current_user.user_name}")
+ log(f"sco_users: previous_values={initvalues}")
+ log(f"sco_users: new_values={vals}")
sco_users.user_edit(user_name, vals)
+ flash(f"Utilisateur {user_name} modifié")
return flask.redirect(
- "user_info_page?user_name=%s&head_message=Utilisateur %s modifié"
- % (user_name, user_name)
+ url_for(
+ "users.user_info_page",
+ scodoc_dept=g.scodoc_dept,
+ user_name=user_name,
+ )
)
- else: # creation utilisateur
+
+ else: # création utilisateur
vals["roles_string"] = ",".join(vals["roles"])
# check identifiant
if not re.match(r"^[a-zA-Z0-9@\\\-_\\\.]+$", vals["user_name"]):
@@ -623,8 +624,7 @@ def create_user_form(user_name=None, edit=0, all_roles=False):
raise ScoValueError("département invalide")
# ok, go
log(
- "sco_users: new_user %s by %s"
- % (vals["user_name"], current_user.user_name)
+ f"""sco_users: new_user {vals["user_name"]} by {current_user.user_name}"""
)
the_user = User()
the_user.from_dict(vals, new_user=True)
@@ -678,7 +678,8 @@ def import_users_form():
H = [
head,
"""Téléchargement d'une nouvelle liste d'utilisateurs
- A utiliser pour importer de nouveaux utilisateurs (enseignants ou secrétaires)
+
A utiliser pour importer de nouveaux
+ utilisateurs (enseignants ou secrétaires)
L'opération se déroule en deux étapes. Dans un premier temps,
@@ -690,7 +691,7 @@ def import_users_form():
""",
]
- help = """
+ help_msg = """
Lors de la creation des utilisateurs, les opérations suivantes sont effectuées:
@@ -727,28 +728,34 @@ def import_users_form():
submitlabel="Télécharger",
)
if tf[0] == 0:
- return "\n".join(H) + tf[1] + "
" + help + F
+ return "\n".join(H) + tf[1] + "" + help_msg + F
elif tf[0] == -1:
return flask.redirect(url_for("scolar.index_html", docodc_dept=g.scodoc_dept))
- else:
- # IMPORT
- ok, diag, nb_created = sco_import_users.import_excel_file(
- tf[2]["xlsfile"], tf[2]["force"]
+
+ # IMPORT
+ ok, diags, nb_created = sco_import_users.import_excel_file(
+ tf[2]["xlsfile"], tf[2]["force"]
+ )
+ H = [html_sco_header.sco_header(page_title="Import utilisateurs")]
+ H.append("")
+ for diag in diags:
+ H.append(f"- {diag}
")
+ H.append("
")
+ if ok:
+ dest_url = url_for("users.index_html", scodoc_dept=g.scodoc_dept, all_depts=1)
+ H.append(
+ f"""Ok, Import terminé ({nb_created} utilisateurs créés)!
+ Continuer
+ """
)
- H = [html_sco_header.sco_header(page_title="Import utilisateurs")]
- H.append("")
- for d in diag:
- H.append("- %s
" % d)
- H.append("
")
- if ok:
- dest = url_for("users.index_html", scodoc_dept=g.scodoc_dept, all_depts=1)
- H.append("Ok, Import terminé (%s utilisateurs créés)!
" % nb_created)
- H.append('Continuer
' % dest)
- else:
- dest = url_for("users.import_users_form", scodoc_dept=g.scodoc_dept)
- H.append("Erreur, importation annulée !
")
- H.append('Continuer
' % dest)
- return "\n".join(H) + html_sco_header.sco_footer()
+ else:
+ dest_url = url_for("users.import_users_form", scodoc_dept=g.scodoc_dept)
+ H.append(
+ f"""Erreur, importation annulée !
+ Continuer
+ """
+ )
+ return "\n".join(H) + html_sco_header.sco_footer()
@bp.route("/user_info_page")
@@ -759,11 +766,9 @@ def user_info_page(user_name=None):
"""Display page of info about given user.
If user_name not specified, user current_user
"""
- from app.scodoc.sco_permissions_check import can_handle_passwd
-
if user_name is not None: # scodoc7func converti en int !
user_name = str(user_name)
- # peut on divulguer ces infos ?
+ # peut-on divulguer ces infos ?
if not can_handle_passwd(current_user, allow_admindepts=True):
raise AccessDenied("Vous n'avez pas la permission de voir cette page")
@@ -877,26 +882,29 @@ def change_password(user_name, password, password2):
if not can_handle_passwd(u):
# access denied
log(
- "change_password: access denied (authuser=%s, user_name=%s)"
- % (current_user, user_name)
+ f"change_password: access denied (authuser={current_user}, user_name={user_name})"
)
raise AccessDenied("vous n'avez pas la permission de changer ce mot de passe")
H = []
F = html_sco_header.sco_footer()
# check password
+ dest_url = url_for(
+ "users.form_change_password", scodoc_dept=g.scodoc_dept, user_name=user_name
+ )
if password != password2:
H.append(
- """Les deux mots de passes saisis sont différents !
- Recommencer
"""
- % user_name
+ f"""Les deux mots de passes saisis sont différents !
+ Recommencer
+ """
)
else:
if not is_valid_password(password):
H.append(
- """ce mot de passe n\'est pas assez compliqué !
(oui, il faut un mot de passe vraiment compliqué !)
- Recommencer
- """
- % user_name
+ f"""ce mot de passe n'est pas assez compliqué !
+
(oui, il faut un mot de passe vraiment compliqué !)
+
+ Recommencer
+ """
)
else:
# ok, strong password
@@ -907,21 +915,26 @@ def change_password(user_name, password, password2):
# ici page simplifiee car on peut ne plus avoir
# le droit d'acceder aux feuilles de style
H.append(
- "Changement effectué !
Ne notez pas ce mot de passe, mais mémorisez le !
Rappel: il est interdit de communiquer son mot de passe à un tiers, même si c'est un collègue de confiance !
Si vous n'êtes pas administrateur, le système va vous redemander votre login et nouveau mot de passe au prochain accès.
"
+ """Changement effectué !
+ Ne notez pas ce mot de passe, mais mémorisez le !
+ Rappel: il est interdit de communiquer son mot de passe à
+ un tiers, même si c'est un collègue de confiance !
+ Si vous n'êtes pas administrateur, le système va vous redemander
+ votre login et nouveau mot de passe au prochain accès.
+
"""
)
return (
- """
-
+ f"""
+
Mot de passe changé
-
+
Mot de passe changé !
"""
- % (scu.SCO_ENCODING, scu.SCO_ENCODING)
+ "\n".join(H)
- + 'Continuer'
- % scu.ScoURL()
+ + f'Continuer