1
0
forked from ScoDoc/ScoDoc

code cosmetic (warnings pylint)

This commit is contained in:
Emmanuel Viennet 2022-08-26 09:43:37 +02:00
parent 5d527edb71
commit 6edecb6659

View File

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