Merge branch 'update_reset_password_form' into 'main'

update and fix password form

See merge request yaal/canaille!207
This commit is contained in:
sebastien yaal 2024-12-23 13:26:38 +00:00
commit 2ebd5ad92c
6 changed files with 155 additions and 101 deletions

View file

@ -322,6 +322,9 @@ def registration(data=None, hash=None):
]
form["password2"].validators = [
wtforms.validators.DataRequired(),
wtforms.validators.EqualTo(
"password1", message=_("Password and confirmation do not match.")
),
]
form["password1"].flags.required = True
form["password2"].flags.required = True

View file

@ -68,7 +68,12 @@ class ForgottenPasswordForm(Form):
class PasswordResetForm(Form):
password = wtforms.PasswordField(
_("Password"),
validators=[wtforms.validators.DataRequired()],
validators=[
wtforms.validators.DataRequired(),
password_length_validator,
password_too_long_validator,
compromised_password_validator,
],
render_kw={
"autocomplete": "new-password",
},

View file

@ -118,7 +118,7 @@ del_button=false
{% endfor %}
{% endif %}
{% if field.name == "password1" and field.data|password_strength and not field.errors %}
{% if (field.name == "password1" or field.name == "password") and field.data|password_strength and not field.errors %}
<div>
<p class="progress_bar">{% trans %}Password strength{% endtrans %}</p>
<div class="ui indicating progress" data-percent="{{ field.data|password_strength }}">

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-12-20 09:35+0100\n"
"POT-Creation-Date: 2024-12-23 10:40+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -88,8 +88,8 @@ msgstr ""
msgid "John Doe"
msgstr ""
#: canaille/backends/ldap/backend.py:179 canaille/core/endpoints/forms.py:105
#: canaille/core/endpoints/forms.py:372
#: canaille/backends/ldap/backend.py:179 canaille/core/endpoints/forms.py:110
#: canaille/core/endpoints/forms.py:377
msgid "jdoe"
msgstr ""
@ -201,8 +201,8 @@ msgstr ""
msgid "You are already logged in, you cannot create an account."
msgstr ""
#: canaille/core/endpoints/account.py:301 canaille/core/endpoints/forms.py:256
#: canaille/core/endpoints/forms.py:390 canaille/templates/base.html:80
#: canaille/core/endpoints/account.py:301 canaille/core/endpoints/forms.py:261
#: canaille/core/endpoints/forms.py:395 canaille/templates/base.html:80
#: canaille/templates/core/groups.html:10
#: canaille/templates/core/groups.html:28
#: canaille/templates/core/partial/group-members.html:15
@ -210,124 +210,129 @@ msgstr ""
msgid "Groups"
msgstr ""
#: canaille/core/endpoints/account.py:337
#: canaille/core/endpoints/account.py:426
#: canaille/core/endpoints/account.py:326 canaille/core/endpoints/forms.py:85
#: canaille/core/endpoints/forms.py:224
msgid "Password and confirmation do not match."
msgstr ""
#: canaille/core/endpoints/account.py:340
#: canaille/core/endpoints/account.py:429
msgid "User account creation failed."
msgstr ""
#: canaille/core/endpoints/account.py:346
#: canaille/core/endpoints/account.py:349
msgid "Your account has been created successfully."
msgstr ""
#: canaille/core/endpoints/account.py:361
#: canaille/core/endpoints/account.py:383
#: canaille/core/endpoints/account.py:364
#: canaille/core/endpoints/account.py:386
msgid "The email confirmation link that brought you here is invalid."
msgstr ""
#: canaille/core/endpoints/account.py:368
#: canaille/core/endpoints/account.py:371
msgid "The email confirmation link that brought you here has expired."
msgstr ""
#: canaille/core/endpoints/account.py:375
#: canaille/core/endpoints/account.py:378
msgid "The invitation link that brought you here was invalid."
msgstr ""
#: canaille/core/endpoints/account.py:390
#: canaille/core/endpoints/account.py:393
msgid "This address email have already been confirmed."
msgstr ""
#: canaille/core/endpoints/account.py:397
#: canaille/core/endpoints/account.py:400
msgid "This address email is already associated with another account."
msgstr ""
#: canaille/core/endpoints/account.py:404
#: canaille/core/endpoints/account.py:407
msgid "Your email address have been confirmed."
msgstr ""
#: canaille/core/endpoints/account.py:434
#: canaille/core/endpoints/account.py:437
msgid "User account creation succeed."
msgstr ""
#: canaille/core/endpoints/account.py:610
#: canaille/core/endpoints/account.py:798
#: canaille/core/endpoints/account.py:613
#: canaille/core/endpoints/account.py:801
msgid "Profile edition failed."
msgstr ""
#: canaille/core/endpoints/account.py:620
#: canaille/core/endpoints/account.py:816
#: canaille/core/endpoints/account.py:623
#: canaille/core/endpoints/account.py:819
msgid "Profile updated successfully."
msgstr ""
#: canaille/core/endpoints/account.py:628
#: canaille/core/endpoints/account.py:631
msgid "Email addition failed."
msgstr ""
#: canaille/core/endpoints/account.py:633
#: canaille/core/endpoints/account.py:636
msgid ""
"An email has been sent to the email address. Please check your inbox and "
"click on the verification link it contains"
msgstr ""
#: canaille/core/endpoints/account.py:640
#: canaille/core/endpoints/account.py:643
msgid "Could not send the verification email"
msgstr ""
#: canaille/core/endpoints/account.py:650
#: canaille/core/endpoints/account.py:653
msgid "Email deletion failed."
msgstr ""
#: canaille/core/endpoints/account.py:653
#: canaille/core/endpoints/account.py:656
msgid "The email have been successfully deleted."
msgstr ""
#: canaille/core/endpoints/account.py:692
#: canaille/core/endpoints/account.py:695
msgid ""
"A password initialization link has been sent at the user email address. "
"It should be received within a few minutes."
msgstr ""
#: canaille/core/endpoints/account.py:699 canaille/core/endpoints/auth.py:183
#: canaille/core/endpoints/account.py:702 canaille/core/endpoints/auth.py:183
msgid "Could not send the password initialization email"
msgstr ""
#: canaille/core/endpoints/account.py:710
#: canaille/core/endpoints/account.py:713
msgid ""
"A password reset link has been sent at the user email address. It should "
"be received within a few minutes."
msgstr ""
#: canaille/core/endpoints/account.py:717
#: canaille/core/endpoints/account.py:720
msgid "Could not send the password reset email"
msgstr ""
#: canaille/core/endpoints/account.py:733
#: canaille/core/endpoints/account.py:736
msgid "The account has been locked"
msgstr ""
#: canaille/core/endpoints/account.py:744
#: canaille/core/endpoints/account.py:747
msgid "The account has been unlocked"
msgstr ""
#: canaille/core/endpoints/account.py:757
#: canaille/core/endpoints/account.py:760
msgid "One-time password authentication has been reset"
msgstr ""
#: canaille/core/endpoints/account.py:836
#: canaille/core/endpoints/account.py:839
#, python-format
msgid "The user %(user)s has been successfully deleted"
msgstr ""
#: canaille/core/endpoints/account.py:853
#: canaille/core/endpoints/account.py:856
msgid "Locked users cannot be impersonated."
msgstr ""
#: canaille/core/endpoints/account.py:857 canaille/core/endpoints/auth.py:134
#: canaille/core/endpoints/account.py:860 canaille/core/endpoints/auth.py:134
#: canaille/core/endpoints/auth.py:367
#, python-format
msgid "Connection successful. Welcome %(user)s"
msgstr ""
#: canaille/core/endpoints/account.py:895 canaille/core/endpoints/auth.py:269
#: canaille/core/endpoints/account.py:898 canaille/core/endpoints/auth.py:269
msgid "Your password has been updated successfully"
msgstr ""
@ -337,9 +342,9 @@ msgid "Email"
msgstr ""
#: canaille/core/endpoints/admin.py:29 canaille/core/endpoints/forms.py:38
#: canaille/core/endpoints/forms.py:61 canaille/core/endpoints/forms.py:150
#: canaille/core/endpoints/forms.py:356 canaille/core/endpoints/forms.py:384
#: canaille/core/endpoints/forms.py:408 canaille/core/endpoints/forms.py:424
#: canaille/core/endpoints/forms.py:61 canaille/core/endpoints/forms.py:155
#: canaille/core/endpoints/forms.py:361 canaille/core/endpoints/forms.py:389
#: canaille/core/endpoints/forms.py:413 canaille/core/endpoints/forms.py:429
msgid "jane.doe@example.com"
msgstr ""
@ -413,29 +418,25 @@ msgid "Login"
msgstr ""
#: canaille/core/endpoints/forms.py:48 canaille/core/endpoints/forms.py:70
#: canaille/core/endpoints/forms.py:204
#: canaille/core/endpoints/forms.py:209
#: canaille/templates/core/profile_settings.html:74
msgid "Password"
msgstr ""
#: canaille/core/endpoints/forms.py:77 canaille/core/endpoints/forms.py:216
#: canaille/core/endpoints/forms.py:82 canaille/core/endpoints/forms.py:221
msgid "Password confirmation"
msgstr ""
#: canaille/core/endpoints/forms.py:80 canaille/core/endpoints/forms.py:219
msgid "Password and confirmation do not match."
msgstr ""
#: canaille/core/endpoints/forms.py:99
#: canaille/core/endpoints/forms.py:104
msgid "Automatic"
msgstr ""
#: canaille/core/endpoints/forms.py:104
#: canaille/core/endpoints/forms.py:109
msgid "Username"
msgstr ""
#: canaille/core/endpoints/forms.py:108 canaille/core/endpoints/forms.py:310
#: canaille/core/endpoints/forms.py:326 canaille/oidc/endpoints/forms.py:29
#: canaille/core/endpoints/forms.py:113 canaille/core/endpoints/forms.py:315
#: canaille/core/endpoints/forms.py:331 canaille/oidc/endpoints/forms.py:29
#: canaille/templates/core/partial/group-members.html:12
#: canaille/templates/core/partial/groups.html:6
#: canaille/templates/core/partial/users.html:12
@ -443,174 +444,174 @@ msgstr ""
msgid "Name"
msgstr ""
#: canaille/core/endpoints/forms.py:110
#: canaille/core/endpoints/forms.py:115
msgid "Title"
msgstr ""
#: canaille/core/endpoints/forms.py:110
#: canaille/core/endpoints/forms.py:115
msgid "Vice president"
msgstr ""
#: canaille/core/endpoints/forms.py:113
#: canaille/core/endpoints/forms.py:118
msgid "Given name"
msgstr ""
#: canaille/core/endpoints/forms.py:115
#: canaille/core/endpoints/forms.py:120
msgid "John"
msgstr ""
#: canaille/core/endpoints/forms.py:121
#: canaille/core/endpoints/forms.py:126
msgid "Family Name"
msgstr ""
#: canaille/core/endpoints/forms.py:124
#: canaille/core/endpoints/forms.py:129
msgid "Doe"
msgstr ""
#: canaille/core/endpoints/forms.py:130
#: canaille/core/endpoints/forms.py:135
msgid "Display Name"
msgstr ""
#: canaille/core/endpoints/forms.py:133
#: canaille/core/endpoints/forms.py:138
msgid "Johnny"
msgstr ""
#: canaille/core/endpoints/forms.py:140 canaille/core/endpoints/forms.py:414
#: canaille/core/endpoints/forms.py:145 canaille/core/endpoints/forms.py:419
#: canaille/templates/core/profile_edit.html:188
msgid "Email addresses"
msgstr ""
#: canaille/core/endpoints/forms.py:146 canaille/core/endpoints/forms.py:404
#: canaille/core/endpoints/forms.py:151 canaille/core/endpoints/forms.py:409
msgid ""
"This email will be used as a recovery address to reset the password if "
"needed"
msgstr ""
#: canaille/core/endpoints/forms.py:160
#: canaille/core/endpoints/forms.py:165
msgid "Phone numbers"
msgstr ""
#: canaille/core/endpoints/forms.py:161
#: canaille/core/endpoints/forms.py:166
msgid "555-000-555"
msgstr ""
#: canaille/core/endpoints/forms.py:168
#: canaille/core/endpoints/forms.py:173
msgid "Address"
msgstr ""
#: canaille/core/endpoints/forms.py:170
#: canaille/core/endpoints/forms.py:175
msgid "132, Foobar Street, Gotham City 12401, XX"
msgstr ""
#: canaille/core/endpoints/forms.py:174
#: canaille/core/endpoints/forms.py:179
msgid "Street"
msgstr ""
#: canaille/core/endpoints/forms.py:176
#: canaille/core/endpoints/forms.py:181
msgid "132, Foobar Street"
msgstr ""
#: canaille/core/endpoints/forms.py:180
#: canaille/core/endpoints/forms.py:185
msgid "Postal Code"
msgstr ""
#: canaille/core/endpoints/forms.py:186
#: canaille/core/endpoints/forms.py:191
msgid "Locality"
msgstr ""
#: canaille/core/endpoints/forms.py:188
#: canaille/core/endpoints/forms.py:193
msgid "Gotham City"
msgstr ""
#: canaille/core/endpoints/forms.py:192
#: canaille/core/endpoints/forms.py:197
msgid "Region"
msgstr ""
#: canaille/core/endpoints/forms.py:194
#: canaille/core/endpoints/forms.py:199
msgid "North Pole"
msgstr ""
#: canaille/core/endpoints/forms.py:198
#: canaille/core/endpoints/forms.py:203
msgid "Photo"
msgstr ""
#: canaille/core/endpoints/forms.py:202
#: canaille/core/endpoints/forms.py:207
#: canaille/templates/core/profile_add.html:64
#: canaille/templates/core/profile_edit.html:76
msgid "Delete the photo"
msgstr ""
#: canaille/core/endpoints/forms.py:227
#: canaille/core/endpoints/forms.py:232
msgid "User number"
msgstr ""
#: canaille/core/endpoints/forms.py:229 canaille/core/endpoints/forms.py:235
#: canaille/core/endpoints/forms.py:234 canaille/core/endpoints/forms.py:240
msgid "1234"
msgstr ""
#: canaille/core/endpoints/forms.py:233
#: canaille/core/endpoints/forms.py:238
msgid "Department"
msgstr ""
#: canaille/core/endpoints/forms.py:239
#: canaille/core/endpoints/forms.py:244
msgid "Organization"
msgstr ""
#: canaille/core/endpoints/forms.py:241
#: canaille/core/endpoints/forms.py:246
msgid "Cogip LTD."
msgstr ""
#: canaille/core/endpoints/forms.py:245
#: canaille/core/endpoints/forms.py:250
msgid "Website"
msgstr ""
#: canaille/core/endpoints/forms.py:247
#: canaille/core/endpoints/forms.py:252
msgid "https://mywebsite.tld"
msgstr ""
#: canaille/core/endpoints/forms.py:252
#: canaille/core/endpoints/forms.py:257
msgid "Preferred language"
msgstr ""
#: canaille/core/endpoints/forms.py:262
#: canaille/core/endpoints/forms.py:267
msgid "users, admins …"
msgstr ""
#: canaille/core/endpoints/forms.py:287
#: canaille/core/endpoints/forms.py:292
msgid "Account expiration"
msgstr ""
#: canaille/core/endpoints/forms.py:313
#: canaille/core/endpoints/forms.py:318
msgid "group"
msgstr ""
#: canaille/core/endpoints/forms.py:317 canaille/core/endpoints/forms.py:336
#: canaille/core/endpoints/forms.py:322 canaille/core/endpoints/forms.py:341
#: canaille/templates/core/partial/groups.html:7
msgid "Description"
msgstr ""
#: canaille/core/endpoints/forms.py:350 canaille/core/endpoints/forms.py:377
#: canaille/core/endpoints/forms.py:355 canaille/core/endpoints/forms.py:382
msgid "Email address"
msgstr ""
#: canaille/core/endpoints/forms.py:371
#: canaille/core/endpoints/forms.py:376
msgid "User name"
msgstr ""
#: canaille/core/endpoints/forms.py:375
#: canaille/core/endpoints/forms.py:380
msgid "Username editable by the invitee"
msgstr ""
#: canaille/core/endpoints/forms.py:417
#: canaille/core/endpoints/forms.py:422
msgid "New email address"
msgstr ""
#: canaille/core/endpoints/forms.py:433
#: canaille/core/endpoints/forms.py:438
#: canaille/templates/core/mails/email_otp.txt:5
msgid "One-time password"
msgstr ""
#: canaille/core/endpoints/forms.py:439
#: canaille/core/endpoints/forms.py:444
msgid "123456"
msgstr ""
@ -777,11 +778,11 @@ msgstr ""
msgid "Pre-consent"
msgstr ""
#: canaille/oidc/endpoints/oauth.py:379
#: canaille/oidc/endpoints/oauth.py:388
msgid "You have been disconnected"
msgstr ""
#: canaille/oidc/endpoints/oauth.py:396
#: canaille/oidc/endpoints/oauth.py:405
msgid "You have not been disconnected"
msgstr ""
@ -1101,13 +1102,13 @@ msgstr ""
#: canaille/templates/core/login.html:52
#: canaille/templates/core/mails/registration.txt:5
#: canaille/templates/core/setup-2fa.html:64
#: canaille/templates/core/setup-mfa.html:64
msgid "Continue"
msgstr ""
#: canaille/templates/core/password.html:21
#: canaille/templates/core/setup-2fa.html:32
#: canaille/templates/core/verify-2fa.html:32
#: canaille/templates/core/setup-mfa.html:32
#: canaille/templates/core/verify-mfa.html:32
#, python-format
msgid "Sign in as %(username)s"
msgstr ""
@ -1117,7 +1118,7 @@ msgid "Please enter your password for this account."
msgstr ""
#: canaille/templates/core/password.html:39
#: canaille/templates/core/verify-2fa.html:50
#: canaille/templates/core/verify-mfa.html:50
#, python-format
msgid "I am not %(username)s"
msgstr ""
@ -1189,7 +1190,7 @@ msgid "Send a verification email to validate this address."
msgstr ""
#: canaille/templates/core/profile_edit.html:233
#: canaille/templates/core/verify-2fa.html:51
#: canaille/templates/core/verify-mfa.html:51
msgid "Verify"
msgstr ""
@ -1294,11 +1295,11 @@ msgstr ""
msgid "Impersonate"
msgstr ""
#: canaille/templates/core/setup-2fa.html:34
#: canaille/templates/core/setup-mfa.html:34
msgid "Set up multi-factor authentication."
msgstr ""
#: canaille/templates/core/verify-2fa.html:34
#: canaille/templates/core/verify-mfa.html:34
msgid "One-time password authentication."
msgstr ""

View file

@ -7,6 +7,17 @@ def test_password_reset(testclient, user, backend):
res = testclient.get("/reset/user/" + hash, status=200)
res.form["password"] = "foobarbaz"
res.form["confirmation"] = "foobar"
res = res.form.submit()
res.mustcontain("Password and confirmation do not match.")
res.mustcontain('data-percent="50"')
res.form["password"] = "123"
res.form["confirmation"] = "123"
res = res.form.submit()
res.mustcontain("Field must be at least 8 characters long.")
res.form["password"] = "foobarbaz"
res.form["confirmation"] = "foobarbaz"
res = res.form.submit()

View file

@ -29,6 +29,40 @@ def test_registration_without_email_validation(testclient, backend, foo_group):
backend.delete(user)
def test_registration_failure_with_different_passwords_and_too_short_password(
testclient, backend, foo_group
):
"""Tests a nominal registration without email validation but with a wrong confirmation password and a too short password."""
testclient.app.config["CANAILLE"]["ENABLE_REGISTRATION"] = True
testclient.app.config["CANAILLE"]["EMAIL_CONFIRMATION"] = False
assert not backend.query(models.User, user_name="newuser")
res = testclient.get(url_for("core.account.registration"), status=200)
res.form["user_name"] = "newuser"
res.form["password1"] = "123"
res.form["password2"] = "123"
res.form["family_name"] = "newuser"
res.form["emails-0"] = "newuser@example.test"
res = res.form.submit()
assert ("error", "User account creation failed.") in res.flashes
res.mustcontain("Field must be at least 8 characters long.")
res.form["password1"] = "i'm a little pea"
res.form["password2"] = "i'm not a little pea"
res = res.form.submit()
res.mustcontain("Password and confirmation do not match.")
res.mustcontain('data-percent="100"')
res.form["password1"] = "i'm a little pea"
res.form["password2"] = "i'm a little pea"
res = res.form.submit()
assert ("success", "Your account has been created successfully.") in res.flashes
user = backend.get(models.User, user_name="newuser")
assert user
backend.delete(user)
def test_registration_with_email_validation(testclient, backend, smtpd, foo_group):
"""Tests a nominal registration with email validation."""
testclient.app.config["CANAILLE"]["ENABLE_REGISTRATION"] = True