Form change password. Codage UTF-8 par défaut provisoirement.

This commit is contained in:
Emmanuel Viennet 2021-07-01 18:54:07 +02:00
parent 46cef02b39
commit a60dfc9df5
9 changed files with 123 additions and 10 deletions

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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 !",

View File

@ -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)

View File

@ -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):

View File

@ -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")

View File

@ -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 !",

View File

@ -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)
+ "<p>Vous n'avez pas la permission de changer ce mot de passe</p>"
+ F
)
#
H.append(
"""<h2>Changement du mot de passe de <font color="red">%(nomplogin)s</font></h2>
<p>
<form action="change_password" method="post"><table>
<tr><td>Nouveau mot de passe:</td><td><input type="password" size="14" name="password"/></td></tr>
<tr><td>Confirmation: </td><td><input type="password" size="14" name="password2" /></td></tr>
</table>
<input type="hidden" value="%(user_name)s" name="user_name">
<input type="submit" value="Changer">
</p>
<p>Vous pouvez aussi: <a class="stdlink" href="reset_password_form?user_name=%(user_name)s">renvoyer un mot de passe aléatoire temporaire par mail à l'utilisateur</a>
"""
% {"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(
"""<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>"""
% user_name
)
else:
if not sco_users.is_valid_password(password):
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>
<p><a href="form_change_password?user_name=%s" class="stdlink">Recommencer</a></p>
"""
% 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(
"<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 (
"""<?xml version="1.0" encoding="%s"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Mot de passe changé</title>
<meta http-equiv="Content-Type" content="text/html; charset=%s" />
<body><h1>Mot de passe changé !</h1>
"""
% (scu.SCO_ENCODING, scu.SCO_ENCODING)
+ "\n".join(H)
+ '<a href="%s" class="stdlink">Continuer</a></body></html>'
% scu.ScoURL()
)
return html_sco_header.sco_header(context, REQUEST) + "\n".join(H) + F