From a60dfc9df5789942d77975d756e08dbec3cd81dd Mon Sep 17 00:00:00 2001
From: Emmanuel Viennet
Date: Thu, 1 Jul 2021 18:54:07 +0200
Subject: [PATCH] =?UTF-8?q?Form=20change=20password.=20Codage=20UTF-8=20pa?=
=?UTF-8?q?r=20d=C3=A9faut=20provisoirement.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/__init__.py | 6 ++
app/auth/models.py | 1 +
app/decorators.py | 2 +-
app/scodoc/sco_formsemestre_edit.py | 8 +--
app/scodoc/sco_permissions_check.py | 2 +
app/scodoc/sco_utils.py | 6 +-
app/views/essais.py | 2 +-
app/views/notes.py | 4 +-
app/views/users.py | 102 +++++++++++++++++++++++++++-
9 files changed, 123 insertions(+), 10 deletions(-)
diff --git a/app/__init__.py b/app/__init__.py
index cb030ad51c..9c08293675 100644
--- a/app/__init__.py
+++ b/app/__init__.py
@@ -2,6 +2,12 @@
# pylint: disable=invalid-name
import os
+import sys
+
+# Un hack en attendant la migration vers Python3 #sco8
+reload(sys)
+sys.setdefaultencoding("UTF8")
+
import logging
from logging.handlers import SMTPHandler, RotatingFileHandler
diff --git a/app/auth/models.py b/app/auth/models.py
index 395f80be39..ea7b3d1b8e 100644
--- a/app/auth/models.py
+++ b/app/auth/models.py
@@ -72,6 +72,7 @@ class User(UserMixin, db.Model):
def set_password(self, password):
"Set password"
+ current_app.logger.info("set_password({})".format(self))
if password:
self.password_hash = generate_password_hash(password)
else:
diff --git a/app/decorators.py b/app/decorators.py
index c522768201..a5a451aa8f 100644
--- a/app/decorators.py
+++ b/app/decorators.py
@@ -95,7 +95,7 @@ def permission_required(permission):
@wraps(f)
def decorated_function(*args, **kwargs):
if "scodoc_dept" in kwargs:
- g.scodoc_dept = kwargs["scodoc_dept"]
+ g.scodoc_dept = kwargs["scodoc_dept"].encode("utf-8") # sco8
del kwargs["scodoc_dept"]
# current_app.logger.info(
# "permission_required: %s in %s" % (permission, g.scodoc_dept)
diff --git a/app/scodoc/sco_formsemestre_edit.py b/app/scodoc/sco_formsemestre_edit.py
index e31be3afe5..1ac8a6b980 100644
--- a/app/scodoc/sco_formsemestre_edit.py
+++ b/app/scodoc/sco_formsemestre_edit.py
@@ -270,7 +270,7 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
"allowed_values": allowed_user_names,
"allow_null": False, # il faut au moins un responsable de semestre
"text_suggest_options": {
- "script": "Users/get_userlist_xml?",
+ "script": "Users/get_user_list_xml?",
"varname": "start",
"json": False,
"noresults": "Valeur invalide !",
@@ -288,7 +288,7 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
"allowed_values": allowed_user_names,
"allow_null": True, # optionnel
"text_suggest_options": {
- "script": "Users/get_userlist_xml?",
+ "script": "Users/get_user_list_xml?",
"varname": "start",
"json": False,
"noresults": "Valeur invalide !",
@@ -572,7 +572,7 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
"allowed_values": allowed_user_names,
"template": itemtemplate,
"text_suggest_options": {
- "script": "Users/get_userlist_xml?",
+ "script": "Users/get_user_list_xml?",
"varname": "start",
"json": False,
"noresults": "Valeur invalide !",
@@ -933,7 +933,7 @@ def formsemestre_clone(context, formsemestre_id, REQUEST=None):
"allowed_values": allowed_user_names,
"allow_null": False,
"text_suggest_options": {
- "script": "Users/get_userlist_xml?",
+ "script": "Users/get_user_list_xml?",
"varname": "start",
"json": False,
"noresults": "Valeur invalide !",
diff --git a/app/scodoc/sco_permissions_check.py b/app/scodoc/sco_permissions_check.py
index 60b9a9a4b8..b4491addd3 100644
--- a/app/scodoc/sco_permissions_check.py
+++ b/app/scodoc/sco_permissions_check.py
@@ -198,6 +198,8 @@ def can_handle_passwd(user, allow_admindepts=False):
and add roles to them).
user is a User instance.
"""
+ if not user:
+ return False
if current_user.is_administrator():
return True # super admin
# Anyone can change his own passwd (or see his informations)
diff --git a/app/scodoc/sco_utils.py b/app/scodoc/sco_utils.py
index ee025b07e5..cd0775927a 100644
--- a/app/scodoc/sco_utils.py
+++ b/app/scodoc/sco_utils.py
@@ -388,7 +388,11 @@ def UsersURL():
= url de base des requêtes ZScoUsers
et page accueil users
"""
- return "NotImplemented"
+ return url_for("users.index_html", scodoc_dept=g.scodoc_dept)[
+ : -len("/index_html")
+ ].encode(
+ SCO_ENCODING
+ ) # sco8
def get_current_user_name(REQUEST):
diff --git a/app/views/essais.py b/app/views/essais.py
index 0a0bfde453..1a49cadc4d 100644
--- a/app/views/essais.py
+++ b/app/views/essais.py
@@ -84,4 +84,4 @@ import flask
@bp.route("/essrep")
def essrep():
- return flask.Response(status=200, response="Bonjour")
+ return flask.Response(status=200, response="Bonjour pépé %s" + u"papa")
diff --git a/app/views/notes.py b/app/views/notes.py
index 67a7827798..9fcae794c3 100644
--- a/app/views/notes.py
+++ b/app/views/notes.py
@@ -756,7 +756,7 @@ def edit_enseignants_form(context, REQUEST, moduleimpl_id):
"allowed_values": allowed_user_names,
"allow_null": False,
"text_suggest_options": {
- "script": "Users/get_userlist_xml?",
+ "script": "Users/get_user_list_xml?",
"varname": "start",
"json": False,
"noresults": "Valeur invalide !",
@@ -846,7 +846,7 @@ def edit_moduleimpl_resp(context, REQUEST, moduleimpl_id):
"allowed_values": allowed_user_names,
"allow_null": False,
"text_suggest_options": {
- "script": "Users/get_userlist_xml?",
+ "script": "Users/get_user_list_xml?",
"varname": "start",
"json": False,
"noresults": "Valeur invalide !",
diff --git a/app/views/users.py b/app/views/users.py
index cbdaddeab6..2e92f7fbab 100644
--- a/app/views/users.py
+++ b/app/views/users.py
@@ -40,6 +40,8 @@ from flask import g
from flask import current_app, request
from flask_login import current_user
+from app import db
+
from app.auth.models import Permission
from app.auth.models import User
from app.decorators import (
@@ -55,7 +57,8 @@ from app.scodoc import html_sco_header
from app.scodoc import sco_users
from app.scodoc import sco_utils as scu
from app.scodoc.notes_log import log
-
+from app.scodoc.sco_permissions_check import can_handle_passwd
+from app.scodoc.sco_exceptions import AccessDenied
from app.views import users_bp as bp
@@ -437,3 +440,100 @@ def get_user_list_xml(context, dept=None, start="", limit=25, REQUEST=None):
doc.rs(user["nomplogin"], id=user["user_id"], info="")
doc._pop()
return repr(doc)
+
+
+@bp.route("/form_change_password")
+@permission_required(Permission.ScoView)
+@scodoc7func(context)
+def form_change_password(REQUEST, user_name=None):
+ """Formulaire de changement mot de passe de l'utilisateur user_name.
+ Un utilisateur peut toujours changer son propre mot de passe.
+ """
+ if not user_name:
+ u = current_user
+ else:
+ u = User.query.filter_by(user_name=user_name).first()
+ H = [html_sco_header.sco_header(context, REQUEST, user_check=False)]
+ F = html_sco_header.sco_footer(context, REQUEST)
+ # check access
+ if not can_handle_passwd(u):
+ return (
+ "\n".join(H)
+ + "Vous n'avez pas la permission de changer ce mot de passe
"
+ + F
+ )
+ #
+ H.append(
+ """Changement du mot de passe de %(nomplogin)s
+
+
+ Vous pouvez aussi: renvoyer un mot de passe aléatoire temporaire par mail à l'utilisateur
+"""
+ % {"nomplogin": u.get_nomplogin(), "user_name": user_name}
+ )
+ return "\n".join(H) + F
+
+
+@bp.route("/change_password", methods=["POST"])
+@permission_required(Permission.ScoView)
+@scodoc7func(context)
+def change_password(user_name, password, password2, REQUEST):
+ "Change the password for user given by user_name"
+ u = User.query.filter_by(user_name=user_name).first()
+ # Check access permission
+ if not can_handle_passwd(u):
+ # access denied
+ log(
+ "change_password: access denied (authuser=%s, user_name=%s, ip=%s)"
+ % (REQUEST.AUTHENTICATED_USER, user_name, REQUEST.REMOTE_ADDR)
+ )
+ raise AccessDenied("vous n'avez pas la permission de changer ce mot de passe")
+ H = []
+ F = html_sco_header.sco_footer(context, REQUEST)
+ # check password
+ if password != password2:
+ H.append(
+ """
Les deux mots de passes saisis sont différents !
+ Recommencer
"""
+ % user_name
+ )
+ else:
+ if not sco_users.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
+ )
+ else:
+ # ok, strong password
+ db.session.add(u)
+ u.set_password(password)
+ db.session.commit()
+ #
+ # 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.
"
+ )
+ return (
+ """
+
+
+
+Mot de passe changé
+
+Mot de passe changé !
+"""
+ % (scu.SCO_ENCODING, scu.SCO_ENCODING)
+ + "\n".join(H)
+ + 'Continuer'
+ % scu.ScoURL()
+ )
+ return html_sco_header.sco_header(context, REQUEST) + "\n".join(H) + F