diff --git a/tests/test_selfservice.py b/tests/test_selfservice.py index f36cfe93c42eef6c5cf99cd8f05370fd7a6231f2..da3c94ddd926729d83cb6962a48292fd5f8c4597 100644 --- a/tests/test_selfservice.py +++ b/tests/test_selfservice.py @@ -101,6 +101,19 @@ class TestSelfservice(UffdTestCase): self.assertFalse(ldap.test_user_bind(_user.dn, 'shortpw')) self.assertTrue(ldap.test_user_bind(_user.dn, 'userpassword')) + # Regression test for #100 (login not possible if password contains character disallowed by SASLprep) + def test_change_password_samlprep_invalid(self): + self.login_as('user') + user = request.user + r = self.client.post(path=url_for('selfservice.change_password'), + data={'password1': 'shortpw\n', 'password2': 'shortpw\n'}, + follow_redirects=True) + dump('change_password_samlprep_invalid', r) + self.assertEqual(r.status_code, 200) + _user = request.user + self.assertFalse(ldap.test_user_bind(_user.dn, 'shortpw\n')) + self.assertTrue(ldap.test_user_bind(_user.dn, 'userpassword')) + def test_change_password_mismatch(self): self.login_as('user') user = request.user diff --git a/tests/test_user.py b/tests/test_user.py index 962840db8de6ad9499c7adacdc123b9919caa72b..ea6bb9a6edf363cca20ccdac0e5ff6b7ec6abbc0 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -193,6 +193,7 @@ class TestUserViews(UffdTestCase): self.assertEqual(user_updated.uid, user_unupdated.uid) self.assertEqual(user_updated.loginname, user_unupdated.loginname) self.assertTrue(ldap.test_user_bind(user_updated.dn, 'newpassword')) + self.assertFalse(ldap.test_user_bind(user_updated.dn, self.test_data.get('user').get('password'))) def test_update_invalid_password(self): user_unupdated = self.get_user() @@ -201,10 +202,28 @@ class TestUserViews(UffdTestCase): r = self.client.post(path=url_for('user.update', uid=user_unupdated.uid), data={'loginname': 'testuser', 'mail': 'newuser@example.com', 'displayname': 'New User', 'password': 'A'}, follow_redirects=True) - dump('user_update_password', r) + dump('user_update_invalid_password', r) self.assertEqual(r.status_code, 200) user_updated = self.get_user() self.assertFalse(ldap.test_user_bind(user_updated.dn, 'A')) + self.assertTrue(ldap.test_user_bind(user_updated.dn, self.test_data.get('user').get('password'))) + self.assertEqual(user_updated.displayname, user_unupdated.displayname) + self.assertEqual(user_updated.mail, user_unupdated.mail) + self.assertEqual(user_updated.loginname, user_unupdated.loginname) + + # Regression test for #100 (login not possible if password contains character disallowed by SASLprep) + def test_update_saslprep_invalid_password(self): + user_unupdated = self.get_user() + r = self.client.get(path=url_for('user.show', uid=user_unupdated.uid), follow_redirects=True) + self.assertEqual(r.status_code, 200) + r = self.client.post(path=url_for('user.update', uid=user_unupdated.uid), + data={'loginname': 'testuser', 'mail': 'newuser@example.com', 'displayname': 'New User', + 'password': 'newpassword\n'}, follow_redirects=True) + dump('user_update_saslprep_invalid_password', r) + self.assertEqual(r.status_code, 200) + user_updated = self.get_user() + self.assertFalse(ldap.test_user_bind(user_updated.dn, 'newpassword\n')) + self.assertTrue(ldap.test_user_bind(user_updated.dn, self.test_data.get('user').get('password'))) self.assertEqual(user_updated.displayname, user_unupdated.displayname) self.assertEqual(user_updated.mail, user_unupdated.mail) self.assertEqual(user_updated.loginname, user_unupdated.loginname) @@ -223,6 +242,7 @@ class TestUserViews(UffdTestCase): self.assertEqual(user_updated.mail, user_unupdated.mail) self.assertEqual(user_updated.loginname, user_unupdated.loginname) self.assertFalse(ldap.test_user_bind(user_updated.dn, 'newpassword')) + self.assertTrue(ldap.test_user_bind(user_updated.dn, self.test_data.get('user').get('password'))) def test_update_invalid_display_name(self): user_unupdated = self.get_user() @@ -238,6 +258,7 @@ class TestUserViews(UffdTestCase): self.assertEqual(user_updated.mail, user_unupdated.mail) self.assertEqual(user_updated.loginname, user_unupdated.loginname) self.assertFalse(ldap.test_user_bind(user_updated.dn, 'newpassword')) + self.assertTrue(ldap.test_user_bind(user_updated.dn, self.test_data.get('user').get('password'))) def test_show(self): r = self.client.get(path=url_for('user.show', uid=self.get_user().uid), follow_redirects=True) diff --git a/uffd/selfservice/templates/selfservice/self.html b/uffd/selfservice/templates/selfservice/self.html index edee7bdc1d5fe7ab8c93ca2072785f5d6e5c174e..158e3f3dfbc92176b87bb1ceac50960e54690f2c 100644 --- a/uffd/selfservice/templates/selfservice/self.html +++ b/uffd/selfservice/templates/selfservice/self.html @@ -47,9 +47,9 @@ <div class="col-12 col-md-7"> <form class="form" action="{{ url_for("selfservice.change_password") }}" method="POST"> <div class="form-group"> - <input type="password" class="form-control" id="user-password1" name="password1" placeholder="{{_("New Password")}}" required> + <input type="password" class="form-control" id="user-password1" name="password1" placeholder="{{_("New Password")}}" minlength={{ User.PASSWORD_MINLEN }} maxlength={{ User.PASSWORD_MAXLEN }} pattern="{{ User.PASSWORD_REGEX }}" required> <small class="form-text text-muted"> - {{_('At least 8 and at most 256 characters, no other special requirements.')}} + {{ User.PASSWORD_DESCRIPTION|safe }} </small> </div> <div class="form-group"> diff --git a/uffd/selfservice/templates/selfservice/set_password.html b/uffd/selfservice/templates/selfservice/set_password.html index 42eaa8660c3f90ac927f51ba2583e981ea8fa46f..ff4c447895b3c52a3beb927e090403e89ed4d567 100644 --- a/uffd/selfservice/templates/selfservice/set_password.html +++ b/uffd/selfservice/templates/selfservice/set_password.html @@ -12,14 +12,14 @@ </div> <div class="form-group col-12"> <label for="user-password1">{{_("New Password")}}</label> - <input type="password" class="form-control" id="user-password1" name="password1" required="required" tabindex = "2"> + <input type="password" class="form-control" id="user-password1" name="password1" tabindex="2" minlength={{ User.PASSWORD_MINLEN }} maxlength={{ User.PASSWORD_MAXLEN }} pattern="{{ User.PASSWORD_REGEX }}" required> <small class="form-text text-muted"> - {{_("At least 8 and at most 256 characters, no other special requirements. But please use a password manager.")}} + {{ User.PASSWORD_DESCRIPTION|safe }} </small> </div> <div class="form-group col-12"> <label for="user-password2">{{_("Repeat Password")}}</label> - <input type="password" class="form-control" id="user-password2" name="password2" required="required" tabindex = "2"> + <input type="password" class="form-control" id="user-password2" name="password2" tabindex="3" required> </div> <div class="form-group col-12"> <button type="submit" class="btn btn-primary btn-block" tabindex = "3">{{_("Set password")}}</button> diff --git a/uffd/signup/templates/signup/start.html b/uffd/signup/templates/signup/start.html index a60dbdb2f3270f48f3e1fcff09bf955fd4e74411..ad150f4ba5f538aefb85ba7a6b6cdeceef9e81ec 100644 --- a/uffd/signup/templates/signup/start.html +++ b/uffd/signup/templates/signup/start.html @@ -44,9 +44,9 @@ </div> <div class="form-group col-12"> <label for="user-password1">{{_('Password')}}</label> - <input type="password" class="form-control" id="user-password1" name="password1" minlength=8 maxlength=256 required> + <input type="password" class="form-control" id="user-password1" name="password1" minlength={{ User.PASSWORD_MINLEN }} maxlength={{ User.PASSWORD_MAXLEN }} pattern="{{ User.PASSWORD_REGEX }}" required> <small class="form-text text-muted"> - {{_("At least 8 and at most 256 characters, no other special requirements. But please use a password manager.")}} + {{ User.PASSWORD_DESCRIPTION|safe }} </small> </div> <div class="form-group col-12"> diff --git a/uffd/translations/de/LC_MESSAGES/messages.mo b/uffd/translations/de/LC_MESSAGES/messages.mo index 73a0ce629d71d5336446229934354d0b64f25f98..e58966921aed2726349395182b5de736f144f297 100644 Binary files a/uffd/translations/de/LC_MESSAGES/messages.mo and b/uffd/translations/de/LC_MESSAGES/messages.mo differ diff --git a/uffd/translations/de/LC_MESSAGES/messages.po b/uffd/translations/de/LC_MESSAGES/messages.po index 3e355080052e5b91ae7a0cb69aacff3069bba8ec..bae852ddaffca378b3c2dd4a5f706f31bdc68363 100644 --- a/uffd/translations/de/LC_MESSAGES/messages.po +++ b/uffd/translations/de/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2021-08-13 14:24+0200\n" +"POT-Creation-Date: 2021-08-30 23:22+0200\n" "PO-Revision-Date: 2021-05-25 21:18+0200\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language: de\n" @@ -267,7 +267,7 @@ msgstr "Enthaltene Rollen" #: uffd/role/templates/role/list.html:14 #: uffd/rolemod/templates/rolemod/list.html:9 #: uffd/rolemod/templates/rolemod/show.html:46 -#: uffd/selfservice/templates/selfservice/self.html:103 +#: uffd/selfservice/templates/selfservice/self.html:101 #: uffd/user/templates/group/list.html:10 #: uffd/user/templates/group/show.html:11 uffd/user/templates/user/show.html:95 #: uffd/user/templates/user/show.html:127 @@ -278,7 +278,7 @@ msgstr "Name" #: uffd/role/templates/role/list.html:15 uffd/role/templates/role/show.html:48 #: uffd/rolemod/templates/rolemod/list.html:10 #: uffd/rolemod/templates/rolemod/show.html:28 -#: uffd/selfservice/templates/selfservice/self.html:104 +#: uffd/selfservice/templates/selfservice/self.html:102 #: uffd/user/templates/group/list.html:11 uffd/user/templates/user/show.html:96 #: uffd/user/templates/user/show.html:128 msgid "Description" @@ -426,7 +426,7 @@ msgid "Two-factor authentication failed" msgstr "Zwei-Faktor-Authentifizierung fehlgeschlagen" #: uffd/mfa/templates/mfa/auth.html:12 -#: uffd/selfservice/templates/selfservice/self.html:69 +#: uffd/selfservice/templates/selfservice/self.html:67 msgid "Two-Factor Authentication" msgstr "Zwei-Faktor-Authentifizierung" @@ -473,12 +473,12 @@ msgid "Disable two-factor authentication" msgstr "Zwei-Faktor-Authentifizierung (2FA) deaktivieren" #: uffd/mfa/templates/mfa/setup.html:18 -#: uffd/selfservice/templates/selfservice/self.html:75 +#: uffd/selfservice/templates/selfservice/self.html:73 msgid "Two-factor authentication is currently <strong>enabled</strong>." msgstr "Die Zwei-Faktor-Authentifizierung ist derzeit <strong>aktiviert</strong>." #: uffd/mfa/templates/mfa/setup.html:20 -#: uffd/selfservice/templates/selfservice/self.html:77 +#: uffd/selfservice/templates/selfservice/self.html:75 msgid "Two-factor authentication is currently <strong>disabled</strong>." msgstr "" "Die Zwei-Faktor-Authentifizierung ist derzeit " @@ -758,11 +758,11 @@ msgstr "" #: uffd/role/views.py:44 uffd/rolemod/views.py:36 uffd/rolemod/views.py:45 #: uffd/rolemod/views.py:60 uffd/session/views.py:130 -#: uffd/user/views_group.py:14 uffd/user/views_user.py:22 +#: uffd/user/views_group.py:14 uffd/user/views_user.py:25 msgid "Access denied" msgstr "Zugriff verweigert" -#: uffd/role/views.py:51 uffd/selfservice/templates/selfservice/self.html:88 +#: uffd/role/views.py:51 uffd/selfservice/templates/selfservice/self.html:86 #: uffd/user/templates/user/list.html:20 uffd/user/templates/user/show.html:21 #: uffd/user/templates/user/show.html:90 msgid "Roles" @@ -797,7 +797,7 @@ msgid "Set as default" msgstr "Als Default setzen" #: uffd/role/templates/role/show.html:19 uffd/role/templates/role/show.html:21 -#: uffd/selfservice/templates/selfservice/self.html:119 +#: uffd/selfservice/templates/selfservice/self.html:117 #: uffd/user/templates/user/show.html:11 msgid "Are you sure?" msgstr "Wirklich fortfahren?" @@ -980,7 +980,7 @@ msgid "Forgot password" msgstr "Passwort vergessen" #: uffd/selfservice/templates/selfservice/forgot_password.html:14 -#: uffd/selfservice/templates/selfservice/self.html:22 +#: uffd/selfservice/templates/selfservice/self.html:21 #: uffd/session/templates/session/login.html:14 #: uffd/signup/templates/signup/start.html:19 #: uffd/user/templates/user/list.html:18 uffd/user/templates/user/show.html:48 @@ -1023,35 +1023,35 @@ msgstr "" msgid "Changes may take serveral minutes to be visible in all services." msgstr "Änderungen sind erst nach einigen Minuten in allen Diensten sichtbar." -#: uffd/selfservice/templates/selfservice/self.html:27 +#: uffd/selfservice/templates/selfservice/self.html:25 #: uffd/signup/templates/signup/start.html:32 #: uffd/user/templates/user/list.html:19 uffd/user/templates/user/show.html:63 msgid "Display Name" msgstr "Anzeigename" -#: uffd/selfservice/templates/selfservice/self.html:31 +#: uffd/selfservice/templates/selfservice/self.html:29 #: uffd/signup/templates/signup/start.html:39 msgid "E-Mail Address" msgstr "E-Mail-Adresse" -#: uffd/selfservice/templates/selfservice/self.html:34 +#: uffd/selfservice/templates/selfservice/self.html:32 msgid "We will send you a confirmation mail to this address if you change it" msgstr "" "Wir werden dir eine Bestätigungsmail zum Setzen der neuen E-Mail-Adresse " "senden." -#: uffd/selfservice/templates/selfservice/self.html:37 +#: uffd/selfservice/templates/selfservice/self.html:35 msgid "Update Profile" msgstr "Änderungen speichern" -#: uffd/selfservice/templates/selfservice/self.html:46 +#: uffd/selfservice/templates/selfservice/self.html:44 #: uffd/session/templates/session/login.html:18 #: uffd/signup/templates/signup/start.html:46 #: uffd/user/templates/user/show.html:77 msgid "Password" msgstr "Passwort" -#: uffd/selfservice/templates/selfservice/self.html:47 +#: uffd/selfservice/templates/selfservice/self.html:45 msgid "" "Your login password for the Single-Sign-On. Only enter it on the Single-" "Sign-On login page! No other legit websites will ask you for this " @@ -1062,27 +1062,22 @@ msgstr "" " Webseite wird dich nach diesem Passwort fragen. Es wird auch niemals für" " Support-Anfragen benötigt." -#: uffd/selfservice/templates/selfservice/self.html:52 +#: uffd/selfservice/templates/selfservice/self.html:50 #: uffd/selfservice/templates/selfservice/set_password.html:14 msgid "New Password" msgstr "Neues Passwort" -#: uffd/selfservice/templates/selfservice/self.html:54 -#: uffd/user/templates/user/show.html:84 -msgid "At least 8 and at most 256 characters, no other special requirements." -msgstr "Mindestens 8 und maximal 256 Zeichen, keine weiteren Einschränkungen." - -#: uffd/selfservice/templates/selfservice/self.html:58 +#: uffd/selfservice/templates/selfservice/self.html:56 #: uffd/selfservice/templates/selfservice/set_password.html:21 #: uffd/signup/templates/signup/start.html:53 msgid "Repeat Password" msgstr "Passwort wiederholen" -#: uffd/selfservice/templates/selfservice/self.html:60 +#: uffd/selfservice/templates/selfservice/self.html:58 msgid "Change Password" msgstr "Passwort ändern" -#: uffd/selfservice/templates/selfservice/self.html:70 +#: uffd/selfservice/templates/selfservice/self.html:68 msgid "" "Setting up Two-Factor Authentication (2FA) adds an additional step to the" " Single-Sign-On login and increases the security of your account " @@ -1092,11 +1087,11 @@ msgstr "" "Anmeldung im Single-Sign-On hinzu und verbessert damit die Sicherheit " "deines Accounts erheblich." -#: uffd/selfservice/templates/selfservice/self.html:80 +#: uffd/selfservice/templates/selfservice/self.html:78 msgid "Manage two-factor authentication" msgstr "Zwei-Faktor-Authentifizierung (2FA) verwalten" -#: uffd/selfservice/templates/selfservice/self.html:89 +#: uffd/selfservice/templates/selfservice/self.html:87 msgid "" "Aside from a set of base permissions, your roles determine the " "permissions of your account." @@ -1104,7 +1099,7 @@ msgstr "" "Deine Berechtigungen werden, von einigen Basis-Berechtigungen abgesehen, " "von deinen Rollen bestimmt" -#: uffd/selfservice/templates/selfservice/self.html:91 +#: uffd/selfservice/templates/selfservice/self.html:89 #, python-format msgid "" "See <a href=\"%(services_url)s\">Services</a> for an overview of your " @@ -1113,17 +1108,17 @@ msgstr "" "Auf <a href=\"%(services_url)s\">Dienste</a> erhälst du einen Überblick " "über deine aktuellen Berechtigungen." -#: uffd/selfservice/templates/selfservice/self.html:96 +#: uffd/selfservice/templates/selfservice/self.html:94 msgid "Administrators and role moderators can invite you to new roles." msgstr "" "Accounts mit Adminrechten oder Rollen-Moderationsrechten können dich zu " "Rollen einladen." -#: uffd/selfservice/templates/selfservice/self.html:98 +#: uffd/selfservice/templates/selfservice/self.html:96 msgid "Administrators can add new roles to your account." msgstr "Accounts mit Adminrechten können dich zu neuen Rollen hinzufügen." -#: uffd/selfservice/templates/selfservice/self.html:113 +#: uffd/selfservice/templates/selfservice/self.html:111 msgid "" "Some permissions in this role require you to setup two-factor " "authentication" @@ -1131,11 +1126,11 @@ msgstr "" "Einige Berechtigungen dieser Rolle erfordern das Einrichten von Zwei-" "Faktor-Authentifikation" -#: uffd/selfservice/templates/selfservice/self.html:120 +#: uffd/selfservice/templates/selfservice/self.html:118 msgid "Leave" msgstr "Verlassen" -#: uffd/selfservice/templates/selfservice/self.html:128 +#: uffd/selfservice/templates/selfservice/self.html:126 msgid "You currently don't have any roles" msgstr "Du hast derzeit keine Rollen" @@ -1143,15 +1138,6 @@ msgstr "Du hast derzeit keine Rollen" msgid "Reset password" msgstr "Passwort zurücksetzen" -#: uffd/selfservice/templates/selfservice/set_password.html:17 -#: uffd/signup/templates/signup/start.html:49 -msgid "" -"At least 8 and at most 256 characters, no other special requirements. But" -" please use a password manager." -msgstr "" -"Mindestens 8 und maximal 256 Zeichen, keine weiteren Einschränkungen. " -"Bitte verwende einen Passwort-Manager." - #: uffd/selfservice/templates/selfservice/set_password.html:25 msgid "Set password" msgstr "Passwort setzen" @@ -1417,45 +1403,56 @@ msgstr "Ändern" msgid "About uffd" msgstr "Über uffd" +#: uffd/user/models.py:52 +#, python-format +msgid "" +"At least %(minlen)d and at most %(maxlen)d characters. Only letters, " +"digits, spaces and some symbols (<code>%(symbols)s</code>) allowed. " +"Please use a password manager." +msgstr "" +"%(minlen)d bis %(maxlen)d Zeichen. Nur Buchstaben, Ziffern, Leerzeichen " +"und manche Symbole (<code>%(symbols)s</code>), keine Umlaute. Bitte " +"verwende einen Passwort-Manager." + #: uffd/user/views_group.py:21 msgid "Groups" msgstr "Gruppen" -#: uffd/user/views_user.py:29 +#: uffd/user/views_user.py:32 msgid "Users" msgstr "Accounts" -#: uffd/user/views_user.py:49 +#: uffd/user/views_user.py:52 msgid "Login name does not meet requirements" msgstr "Anmeldename entspricht nicht den Anforderungen" -#: uffd/user/views_user.py:54 +#: uffd/user/views_user.py:57 msgid "Mail is invalid" msgstr "E-Mail-Adresse nicht valide" -#: uffd/user/views_user.py:58 +#: uffd/user/views_user.py:61 msgid "Display name does not meet requirements" msgstr "Anzeigename entspricht nicht den Anforderungen" -#: uffd/user/views_user.py:63 +#: uffd/user/views_user.py:66 msgid "Password is invalid" msgstr "Passwort ist ungültig" -#: uffd/user/views_user.py:77 +#: uffd/user/views_user.py:80 msgid "Service user created" msgstr "Service-Account erstellt" -#: uffd/user/views_user.py:80 +#: uffd/user/views_user.py:83 msgid "User created. We sent the user a password reset link by mail" msgstr "" "Account erstellt. E-Mail mit einem Link zum Setzen des Passworts wurde " "versendet." -#: uffd/user/views_user.py:82 +#: uffd/user/views_user.py:85 msgid "User updated" msgstr "Account aktualisiert" -#: uffd/user/views_user.py:93 +#: uffd/user/views_user.py:96 msgid "Deleted user" msgstr "Account gelöscht" diff --git a/uffd/user/models.py b/uffd/user/models.py index 81a6e3638aae7b3f3687f0bd5d88ef60ed7e187e..3a3069f758efd45090c2b17a751a8cbe4c4a5e19 100644 --- a/uffd/user/models.py +++ b/uffd/user/models.py @@ -2,7 +2,8 @@ import secrets import string import re -from flask import current_app +from flask import current_app, escape +from flask_babel import lazy_gettext from ldap3.utils.hashed import hashed, HASHED_SALTED_SHA512 from uffd.ldap import ldap @@ -36,6 +37,20 @@ def format_with_attributes(fmtstr, obj): return fmtstr.format_map(ObjectAttributeDict(obj)) class BaseUser(ldap.Model): + # Allows 8 to 256 ASCII letters (lower and upper case), digits, spaces and + # symbols/punctuation characters. It disallows control characters and + # non-ASCII characters to prevent setting passwords considered invalid by + # SASLprep. + # + # This REGEX ist used both in Python and JS. + PASSWORD_REGEX = '[ -~]*' + PASSWORD_MINLEN = 8 + PASSWORD_MAXLEN = 256 + PASSWORD_DESCRIPTION = lazy_gettext('At least %(minlen)d and at most %(maxlen)d characters. ' + \ + 'Only letters, digits, spaces and some symbols (<code>%(symbols)s</code>) allowed. ' + \ + 'Please use a password manager.', + minlen=PASSWORD_MINLEN, maxlen=PASSWORD_MAXLEN, symbols=escape('!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~')) + ldap_search_base = lazyconfig_str('LDAP_USER_SEARCH_BASE') ldap_filter_params = lazyconfig_list('LDAP_USER_SEARCH_FILTER') ldap_object_classes = lazyconfig_list('LDAP_USER_OBJECTCLASSES') @@ -129,7 +144,7 @@ class BaseUser(ldap.Model): return True def set_password(self, value): - if len(value) < 8 or len(value) > 256: + if len(value) < self.PASSWORD_MINLEN or len(value) > self.PASSWORD_MAXLEN or not re.fullmatch(self.PASSWORD_REGEX, value): return False self.password = value return True diff --git a/uffd/user/templates/user/show.html b/uffd/user/templates/user/show.html index 59ef1bd1d0cbaa3d37db4ae62b7554262866f1c9..052dd09a866565df14f7bff81533fa48bf1d81e7 100644 --- a/uffd/user/templates/user/show.html +++ b/uffd/user/templates/user/show.html @@ -76,12 +76,12 @@ <div class="form-group col"> <label for="user-loginname">{{_("Password")}}</label> {% if user.uid %} - <input type="password" class="form-control" id="user-password" name="password" placeholder="●●●●●●●●"> + <input type="password" class="form-control" id="user-password" name="password" placeholder="●●●●●●●●" minlength={{ User.PASSWORD_MINLEN }} maxlength={{ User.PASSWORD_MAXLEN }} pattern="{{ User.PASSWORD_REGEX }}"> {% else %} <input type="password" class="form-control" id="user-password" name="password" placeholder="{{_("mail to set it will be sent")}}" readonly> {% endif %} <small class="form-text text-muted"> - {{_("At least 8 and at most 256 characters, no other special requirements.")}} + {{ User.PASSWORD_DESCRIPTION|safe }} </small> </div> </div> diff --git a/uffd/user/views_user.py b/uffd/user/views_user.py index ee5bc71eed7ee34364f64aa2c092fe94465a315f..2b2739465cc9e376afb73bc57d34e1fde790caa0 100644 --- a/uffd/user/views_user.py +++ b/uffd/user/views_user.py @@ -15,6 +15,9 @@ from uffd.ldap import ldap, LDAPCommitError from .models import User bp = Blueprint("user", __name__, template_folder='templates', url_prefix='/user/') + +bp.add_app_template_global(User, 'User') + @bp.before_request @login_required() def user_acl(): #pylint: disable=inconsistent-return-statements