diff --git a/app/__init__.py b/app/__init__.py index cb030ad5..9c082936 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 395f80be..ea7b3d1b 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 c5227682..a5a451aa 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 e31be3af..1ac8a6b9 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 60b9a9a4..b4491add 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 ee025b07..cd077592 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 0a0bfde4..1a49cadc 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 67a78277..9fcae794 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 cbdaddea..2e92f7fb 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

+

+

+ + +
Nouveau mot de passe:
Confirmation:
+ + +

+

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