forked from ScoDoc/ScoDoc
amélioration formulaires creation/edition utilisateurs
This commit is contained in:
parent
c2de33f7f5
commit
9c50b58d5f
@ -8,7 +8,7 @@ TODO: à revoir complètement pour reprendre ZScoUsers et les pages d'authentifi
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, PasswordField, BooleanField, SubmitField
|
||||
from wtforms.validators import ValidationError, DataRequired, Email, EqualTo
|
||||
from app.auth.models import User
|
||||
from app.auth.models import User, is_valid_password
|
||||
|
||||
|
||||
_ = lambda x: x # sans babel
|
||||
@ -44,7 +44,7 @@ class UserCreationForm(FlaskForm):
|
||||
|
||||
class ResetPasswordRequestForm(FlaskForm):
|
||||
email = StringField(_l("Email"), validators=[DataRequired(), Email()])
|
||||
submit = SubmitField(_l("Request Password Reset"))
|
||||
submit = SubmitField(_l("Valider ce mot de passe"))
|
||||
|
||||
|
||||
class ResetPasswordForm(FlaskForm):
|
||||
@ -52,7 +52,11 @@ class ResetPasswordForm(FlaskForm):
|
||||
password2 = PasswordField(
|
||||
_l("Répéter"), validators=[DataRequired(), EqualTo("password")]
|
||||
)
|
||||
submit = SubmitField(_l("Request Password Reset"))
|
||||
submit = SubmitField(_l("Valider ce mot de passe"))
|
||||
|
||||
def validate_password(self, password):
|
||||
if not is_valid_password(password.data):
|
||||
raise ValidationError(f"Mot de passe trop simple, recommencez")
|
||||
|
||||
|
||||
class DeactivateUserForm(FlaskForm):
|
||||
|
@ -10,6 +10,7 @@ import re
|
||||
from time import time
|
||||
from typing import Optional
|
||||
|
||||
import cracklib # pylint: disable=import-error
|
||||
from flask import current_app, url_for, g
|
||||
from flask_login import UserMixin, AnonymousUserMixin
|
||||
|
||||
@ -28,6 +29,23 @@ from app.scodoc import sco_etud # a deplacer dans scu
|
||||
VALID_LOGIN_EXP = re.compile(r"^[a-zA-Z0-9@\\\-_\.]+$")
|
||||
|
||||
|
||||
def is_valid_password(cleartxt):
|
||||
"""Check password.
|
||||
returns True if OK.
|
||||
"""
|
||||
if (
|
||||
hasattr(scu.CONFIG, "MIN_PASSWORD_LENGTH")
|
||||
and scu.CONFIG.MIN_PASSWORD_LENGTH > 0
|
||||
and len(cleartxt) < scu.CONFIG.MIN_PASSWORD_LENGTH
|
||||
):
|
||||
return False # invalid: too short
|
||||
try:
|
||||
_ = cracklib.FascistCheck(cleartxt)
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
|
||||
class User(UserMixin, db.Model):
|
||||
"""ScoDoc users, handled by Flask / SQLAlchemy"""
|
||||
|
||||
|
@ -116,6 +116,6 @@ def reset_password(token):
|
||||
if form.validate_on_submit():
|
||||
user.set_password(form.password.data)
|
||||
db.session.commit()
|
||||
flash(_("Your password has been reset."))
|
||||
flash(_("Votre mot de passe a été changé."))
|
||||
return redirect(url_for("auth.login"))
|
||||
return render_template("auth/reset_password.html", form=form)
|
||||
return render_template("auth/reset_password.html", form=form, user=user)
|
||||
|
@ -34,7 +34,6 @@ import re
|
||||
from flask import url_for, g, request
|
||||
from flask_login import current_user
|
||||
|
||||
import cracklib # pylint: disable=import-error
|
||||
|
||||
from app import db, Departement
|
||||
|
||||
@ -56,23 +55,6 @@ from app.scodoc.sco_exceptions import (
|
||||
)
|
||||
|
||||
|
||||
def is_valid_password(cleartxt):
|
||||
"""Check password.
|
||||
returns True if OK.
|
||||
"""
|
||||
if (
|
||||
hasattr(scu.CONFIG, "MIN_PASSWORD_LENGTH")
|
||||
and scu.CONFIG.MIN_PASSWORD_LENGTH > 0
|
||||
and len(cleartxt) < scu.CONFIG.MIN_PASSWORD_LENGTH
|
||||
):
|
||||
return False # invalid: too short
|
||||
try:
|
||||
_ = cracklib.FascistCheck(cleartxt)
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
|
||||
# ---------------
|
||||
|
||||
# ---------------
|
||||
@ -439,6 +421,15 @@ def check_modif_user(
|
||||
return False, "département '%s' inexistant" % dept + MSG_OPT
|
||||
if enforce_optionals and not roles:
|
||||
return False, "aucun rôle sélectionné, êtes vous sûr ?" + MSG_OPT
|
||||
# Unicité du mail
|
||||
users_with_this_mail = User.query.filter_by(email=email).all()
|
||||
if edit: # modification
|
||||
if email != user["email"] and len(users_with_this_mail) > 0:
|
||||
return False, "un autre utilisateur existe déjà avec cette adresse mail"
|
||||
else: # création utilisateur
|
||||
if len(users_with_this_mail) > 0:
|
||||
return False, "un autre utilisateur existe déjà avec cette adresse mail"
|
||||
|
||||
# ok
|
||||
# Des noms/prénoms semblables existent ?
|
||||
nom = nom.lower().strip()
|
||||
|
@ -6,7 +6,7 @@ function refresh() {
|
||||
$("#tf_password").closest('tr').css("display", "none");
|
||||
$("#tf_password2").closest('tr').css("display", "none");
|
||||
} else {
|
||||
// Le mot de passe doit être saisi
|
||||
// Le mot de passe doit être saisi
|
||||
$("#tf_password").closest('tr').css("display", "table-row");
|
||||
$("#tf_password2").closest('tr').css("display", "table-row");
|
||||
}
|
||||
@ -18,11 +18,11 @@ function refresh() {
|
||||
}
|
||||
}
|
||||
|
||||
$(function() {
|
||||
$("input[name='welcome:list']").click(function() {
|
||||
$(function () {
|
||||
$("input[name='welcome:list']").click(function () {
|
||||
refresh();
|
||||
})
|
||||
$("input[name='reset_password:list']").click(function() {
|
||||
$("input[name='reset_password:list']").click(function () {
|
||||
refresh();
|
||||
})
|
||||
refresh();
|
||||
|
@ -2,8 +2,13 @@
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>Reset Your Password</h1>
|
||||
<div class="row">
|
||||
<h1>Changez votre mot de passe ScoDoc</h1>
|
||||
|
||||
<div class="row" style="margin-top: 30px;">
|
||||
<div class="col-md-4">Votre identifiant: <b>{{user.user_name}}</b></div>
|
||||
</div>
|
||||
|
||||
<div class="row" style="margin-top: 30px;">
|
||||
<div class="col-md-4">
|
||||
{{ wtf.quick_form(form) }}
|
||||
</div>
|
||||
|
@ -1,16 +1,18 @@
|
||||
<p>Bienvenue {{ user.prenom }} {{ user.nom }},</p>
|
||||
<p>
|
||||
Votre accès à ScoDoc vient d'être validé.
|
||||
votre identifiant de connexion est: {{ user.user_name }}
|
||||
|
||||
{% if token %}
|
||||
Pour initialiser votre mot de passe ScoDoc,
|
||||
</p>
|
||||
<p>
|
||||
Votre identifiant de connexion est: <b>{{ user.user_name }}</b>
|
||||
</p>
|
||||
{% if token %}
|
||||
<p>Pour initialiser votre mot de passe ScoDoc,
|
||||
<a href="{{ url_for('auth.reset_password', token=token, _external=True) }}">
|
||||
cliquez sur ce lien
|
||||
</a>.
|
||||
</p>
|
||||
<p>Vous pouvez aussi copier ce lien dans votre navigateur Web:</p>
|
||||
<p>{{ url_for('auth.reset_password', token=token, _external=True) }}</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<p>A bientôt !</p>
|
@ -49,6 +49,7 @@ from app.auth.models import Permission
|
||||
from app.auth.models import User
|
||||
from app.auth.models import Role
|
||||
from app.auth.models import UserRole
|
||||
from app.auth.models import is_valid_password
|
||||
from app.email import send_email
|
||||
from app.models import Departement
|
||||
|
||||
@ -226,29 +227,6 @@ def create_user_form(user_name=None, edit=0, all_roles=1):
|
||||
},
|
||||
),
|
||||
("formsemestre_id", {"input_type": "hidden"}),
|
||||
(
|
||||
"welcome",
|
||||
{
|
||||
"title": "Message d'accueil",
|
||||
"input_type": "checkbox",
|
||||
"explanation": "Envoie un mail d'accueil à l'utilisateur.",
|
||||
"labels": ("",),
|
||||
"allowed_values": ("1",),
|
||||
"default": "1",
|
||||
},
|
||||
),
|
||||
(
|
||||
"reset_password",
|
||||
{
|
||||
"title": "réinit. mot de passe.",
|
||||
"input_type": "checkbox",
|
||||
"explanation": "ajoute la procédure de changement de mot de passe au mail d'accueil",
|
||||
"labels": ("",),
|
||||
"allowed_values": ("1",),
|
||||
"default": "1",
|
||||
"attributes": ["style='margin-left:20pt'"],
|
||||
},
|
||||
),
|
||||
(
|
||||
"password",
|
||||
{
|
||||
@ -289,6 +267,32 @@ def create_user_form(user_name=None, edit=0, all_roles=1):
|
||||
},
|
||||
)
|
||||
]
|
||||
if not edit: # options création utilisateur
|
||||
descr += [
|
||||
(
|
||||
"welcome",
|
||||
{
|
||||
"title": "Message d'accueil",
|
||||
"input_type": "checkbox",
|
||||
"explanation": "Envoie un mail d'accueil à l'utilisateur.",
|
||||
"labels": ("",),
|
||||
"allowed_values": ("1",),
|
||||
"default": "1",
|
||||
},
|
||||
),
|
||||
(
|
||||
"reset_password",
|
||||
{
|
||||
"title": "",
|
||||
"input_type": "checkbox",
|
||||
"explanation": "indiquer par mail de changer le mot de passe initial",
|
||||
"labels": ("",),
|
||||
"allowed_values": ("1",),
|
||||
"default": "1",
|
||||
# "attributes": ["style='margin-left:20pt'"],
|
||||
},
|
||||
),
|
||||
]
|
||||
|
||||
if not auth_dept:
|
||||
# si auth n'a pas de departement (admin global)
|
||||
@ -479,7 +483,7 @@ def create_user_form(user_name=None, edit=0, all_roles=1):
|
||||
# Traitement initial (mode) : 3 cas
|
||||
# A: envoi de welcome + procedure de reset
|
||||
# B: envoi de welcome seulement (mot de passe saisie dans le formulaire)
|
||||
# C: Aucun envoi (mot de pase saisi dans le formulaire)
|
||||
# C: Aucun envoi (mot de passe saisi dans le formulaire)
|
||||
if vals["welcome:list"] == "1":
|
||||
if vals["reset_password:list"] == "1":
|
||||
mode = "A"
|
||||
@ -498,7 +502,7 @@ def create_user_form(user_name=None, edit=0, all_roles=1):
|
||||
"""Les deux mots de passes ne correspondent pas !"""
|
||||
)
|
||||
return "\n".join(H) + msg + "\n" + tf[1] + F
|
||||
if not sco_users.is_valid_password(vals["password"]):
|
||||
if not is_valid_password(vals["password"]):
|
||||
msg = tf_error_message(
|
||||
"""Mot de passe trop simple, recommencez !"""
|
||||
)
|
||||
@ -521,7 +525,7 @@ def create_user_form(user_name=None, edit=0, all_roles=1):
|
||||
else:
|
||||
token = None
|
||||
send_email(
|
||||
"[ScoDoc] Réinitialisation de votre mot de passe",
|
||||
"[ScoDoc] Création de votre compte",
|
||||
sender=current_app.config["ADMINS"][0],
|
||||
recipients=[u.email],
|
||||
text_body=render_template("email/welcome.txt", user=u, token=token),
|
||||
@ -735,7 +739,7 @@ def change_password(user_name, password, password2):
|
||||
% user_name
|
||||
)
|
||||
else:
|
||||
if not sco_users.is_valid_password(password):
|
||||
if not 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>
|
||||
|
Loading…
Reference in New Issue
Block a user