diff --git a/app/api/auth.py b/app/api/auth.py index 0226976c..24348aab 100644 --- a/app/api/auth.py +++ b/app/api/auth.py @@ -33,7 +33,7 @@ token_auth = HTTPTokenAuth() @basic_auth.verify_password def verify_password(username, password): - user = User.query.filter_by(username=username).first() + user = User.query.filter_by(user_name=username).first() if user and user.check_password(password): return user diff --git a/app/templates/auth/change_password.html b/app/templates/auth/change_password.html new file mode 100644 index 00000000..228982ab --- /dev/null +++ b/app/templates/auth/change_password.html @@ -0,0 +1,46 @@ +{% extends "base.html" %} +{% import 'bootstrap/wtf.html' as wtf %} + +{% macro render_field(field) %} + + {{ field.label }} + {{ field(**kwargs)|safe }} + {% if field.errors %} + + {% endif %} + + +{% endmacro %} + +{% block app_content %} +

Changez vos données personnelles

+

Identifiez vous avez votre mot de passe actuel

+

Vous pouvez changer votre mot de passe (laisez les champs vides sinon)

+

et/ou votre adresse email.

+ +
+ {{ form.user_name }} + {{ form.csrf_token }} + + {{ render_field(form.old_password, size=14, style="padding:1px;") }} + {{ render_field(form.new_password, size=14, style="padding:1px;") }} + {{ render_field(form.bis_password, size=14, style="padding:1px;") }} + {{ render_field(form.email, size=40, style="padding:1px;") }} + {{ render_field(form.submit) }} +
+
+ +{#
#} +{#
Votre identifiant: {{user.user_name}}
#} +{#
#} +{##} +{#
#} +{#
#} +{# {{ wtf.quick_form(form) }}#} +{#
#} +{#
#} +{% endblock %} \ No newline at end of file diff --git a/app/views/users.py b/app/views/users.py index 98d14f30..84f17660 100644 --- a/app/views/users.py +++ b/app/views/users.py @@ -38,12 +38,15 @@ import re from xml.etree import ElementTree import flask -from flask import g, url_for, request, current_app +from flask import g, url_for, request, current_app, flash from flask import redirect, render_template from flask_login import current_user +from wtforms import HiddenField, PasswordField, StringField, SubmitField +from wtforms.validators import DataRequired, Email, ValidationError, EqualTo from app import db +from app.api.auth import verify_password from app.auth.forms import DeactivateUserForm from app.auth.models import Permission from app.auth.models import User @@ -69,6 +72,40 @@ 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): + user_name = HiddenField() + old_password = PasswordField(_l("Ancien mot de passe")) + new_password = PasswordField(_l("Nouveau mot de passe")) + bis_password = PasswordField( + _l("Répéter"), + validators=[ + EqualTo( + "new_password", + message="Les deux saisies sont " "différentes, recommencez", + ), + ], + ) + email = StringField(_l("Email"), validators=[DataRequired(), Email()]) + submit = SubmitField(_l("Modifier")) + + def validate_email(self, email): + user = User.query.filter_by(email=email.data).first() + if user is not None and self.user_name.data != user.user_name: + raise ValidationError(_("Please choose a different email address.")) + + def validate_new_password(self, new_password): + if new_password.data != "" and not is_valid_password(new_password.data): + raise ValidationError(f"Mot de passe trop simple, recommencez") + + def validate_old_password(self, old_password): + if not verify_password(self.user_name.data, old_password.data): + raise ValidationError("Ancien mot de passe incorrect, recommenccez") @bp.route("/") @@ -676,7 +713,7 @@ def get_user_list_xml(dept=None, start="", limit=25): return scu.send_file(data, mime=scu.XML_MIMETYPE) -@bp.route("/form_change_password") +@bp.route("/form_change_password", methods=["GET", "POST"]) @scodoc @permission_required(Permission.ScoView) @scodoc7func @@ -685,36 +722,31 @@ def form_change_password(user_name=None): Un utilisateur peut toujours changer son propre mot de passe. """ if not user_name: - u = current_user + user = current_user else: - u = User.query.filter_by(user_name=user_name).first() - H = [html_sco_header.sco_header(user_check=False)] - F = html_sco_header.sco_footer() + user = User.query.filter_by(user_name=user_name).first() + # 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 + if not can_handle_passwd(user): + return "\n".join( + [ + html_sco_header.sco_header(user_check=False), + "

Vous n'avez pas la permission de changer ce mot de passe

", + html_sco_header.sco_footer(), + ] ) - # - H.append( - """

Changement du mot de passe de %(nomplogin)s

-

-

- - -
Nouveau mot de passe:
Confirmation:
- - -

-

Note: en ScoDoc 9, les utilisateurs peuvent changer eux-même leur mot de passe - en indiquant l'adresse mail associée à leur compte. -

-""" - % {"nomplogin": u.get_nomplogin(), "user_name": user_name} - ) - return "\n".join(H) + F + form = ChangePasswordForm(user_name=user.user_name, email=user.email) + if form.validate_on_submit(): + messages = [] + if form.new_password.data != "": # change password + user.set_password(form.new_password.data) + messages.append("Mot de passe modifié") + if form.email.data != user.email: # change email + user.email = form.email.data + messages.append("Adresse email modifiée") + db.session.commit() + flash("\n".join(messages)) + return render_template("auth/change_password.html", form=form) @bp.route("/change_password", methods=["POST"])