UPD: enable stronger password validation and eventually warning message on login
All checks were successful
buildbot/tox Build done.
All checks were successful
buildbot/tox Build done.
This commit is contained in:
@@ -32,4 +32,38 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-2">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<h3 class="top-most">{% trans 'Passwortrichtlinien' %}</h3>
|
||||||
|
<div class="well">
|
||||||
|
<p>
|
||||||
|
Damit die persönlichen Daten unserer Teilnehmer jederzeit geschützt sind, ist es unabdingbar,
|
||||||
|
dass eure Passwörter für das Touren- & Kurse-Portal nicht einfach zu erraten sind.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Je länger das Passwort ist und je mehr <i>ungewöhnliche</i> Zeichen darin enthalten sind,
|
||||||
|
umso unwahrscheinlicher ist es, dass das Passwort erraten werden kann.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Um sicher zu stellen, dass eure Passwörter ausreichend lang sind und nicht nur
|
||||||
|
aus einfachen Wörtern bestehen, wird die Güte eures Passwortes mit Punkten bewertet.<br />
|
||||||
|
Ausserdem dürfen bestimmte Wörter nicht enthalten sein (z.B. Karlsruhe).
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Mehr Zeichen geben mehr Punkte. Und Großbuchstaben, Ziffern und Sonderzeichen geben Extrapunkte.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Im Regelfall sollte euer Passwort aus mindestens 12 Zeichen bestehen,
|
||||||
|
darunter mindestens je zwei Großbuchstaben, Ziffern und Sonderzeichen.<br />
|
||||||
|
Nehmt da ruhig alles, was eure Tastatur so hergibt.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-3">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock page-container %}
|
{% endblock page-container %}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from ..emails import PasswordSetEmail
|
|||||||
|
|
||||||
|
|
||||||
TEST_USERNAME = 'user'
|
TEST_USERNAME = 'user'
|
||||||
TEST_PASSWORD = u'me||ön 2'
|
TEST_PASSWORD = u'me||ön 21ABll'
|
||||||
TEST_EMAIL = 'root@localhost'
|
TEST_EMAIL = 'root@localhost'
|
||||||
|
|
||||||
PASSWORD_EMAIL_TEMPLATE = u"""Hallo {fullname},
|
PASSWORD_EMAIL_TEMPLATE = u"""Hallo {fullname},
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from dav_base.tests.generic import FormDataSet, FormsTestCase
|
|||||||
from ..forms import LoginForm, SetPasswordForm, CreateAndSendPasswordForm
|
from ..forms import LoginForm, SetPasswordForm, CreateAndSendPasswordForm
|
||||||
|
|
||||||
TEST_USERNAME = 'root@localhost'
|
TEST_USERNAME = 'root@localhost'
|
||||||
TEST_PASSWORD = u'me||ön 2'
|
TEST_PASSWORD = u'me||ön 21ABll'
|
||||||
TEST_EMAIL = TEST_USERNAME
|
TEST_EMAIL = TEST_USERNAME
|
||||||
USERNAME_MAX_LENGTH = 254
|
USERNAME_MAX_LENGTH = 254
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ class SetPasswordFormTestCase(FormsTestCase):
|
|||||||
|
|
||||||
def test_mismatch(self):
|
def test_mismatch(self):
|
||||||
data_sets = [
|
data_sets = [
|
||||||
FormDataSet({'new_password': 'mellon12', 'new_password_repeat': 'mellon13'},
|
FormDataSet({'new_password': 'mellonAB12+-', 'new_password_repeat': 'mellonAB13+-'},
|
||||||
[('new_password_repeat', 'password_mismatch')]),
|
[('new_password_repeat', 'password_mismatch')]),
|
||||||
]
|
]
|
||||||
super(SetPasswordFormTestCase, self).test_invalid_data(data_sets=data_sets, form_kwargs={'user': self.user})
|
super(SetPasswordFormTestCase, self).test_invalid_data(data_sets=data_sets, form_kwargs={'user': self.user})
|
||||||
@@ -150,9 +150,10 @@ class SetPasswordFormTestCase(FormsTestCase):
|
|||||||
|
|
||||||
def test_valid(self):
|
def test_valid(self):
|
||||||
data_sets = [
|
data_sets = [
|
||||||
FormDataSet({'new_password': 'mellon12', 'new_password_repeat': 'mellon12'}),
|
FormDataSet({'new_password': 'mellonAB12+-', 'new_password_repeat': 'mellonAB12+-'}),
|
||||||
FormDataSet({'new_password': 'mellon12', 'new_password_repeat': 'mellon12', 'send_password_mail': True}),
|
FormDataSet({'new_password': 'mellonAB12+-', 'new_password_repeat': 'mellonAB12+-',
|
||||||
FormDataSet({'new_password': u'"ä§ Mellon12', 'new_password_repeat': u'"ä§ Mellon12'}),
|
'send_password_mail': True}),
|
||||||
|
FormDataSet({'new_password': u'"ä§ MellonAB12+-', 'new_password_repeat': u'"ä§ MellonAB12+-'}),
|
||||||
FormDataSet({'new_password': 'mellon12' * 128, 'new_password_repeat': 'mellon12' * 128}),
|
FormDataSet({'new_password': 'mellon12' * 128, 'new_password_repeat': 'mellon12' * 128}),
|
||||||
]
|
]
|
||||||
super(SetPasswordFormTestCase, self).test_valid_data(data_sets=data_sets, form_kwargs={'user': self.user})
|
super(SetPasswordFormTestCase, self).test_valid_data(data_sets=data_sets, form_kwargs={'user': self.user})
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from selenium.webdriver.common.keys import Keys
|
|||||||
from dav_base.tests.generic import ScreenshotTestCase
|
from dav_base.tests.generic import ScreenshotTestCase
|
||||||
|
|
||||||
TEST_USERNAME = 'root@localhost'
|
TEST_USERNAME = 'root@localhost'
|
||||||
TEST_PASSWORD = u'me||ön 2'
|
TEST_PASSWORD = u'me||ön 21ABll'
|
||||||
TEST_EMAIL = TEST_USERNAME
|
TEST_EMAIL = TEST_USERNAME
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ from dav_base.tests.generic import SeleniumTestCase
|
|||||||
from .generic import SeleniumAuthMixin
|
from .generic import SeleniumAuthMixin
|
||||||
|
|
||||||
TEST_USERNAME = 'root@localhost'
|
TEST_USERNAME = 'root@localhost'
|
||||||
TEST_PASSWORD = 'me||ön 2'
|
TEST_PASSWORD = 'me||ön 21ABll'
|
||||||
TEST_EMAIL = TEST_USERNAME
|
TEST_EMAIL = TEST_USERNAME
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -83,22 +83,22 @@ class CustomWordlistPasswordValidatorTestCase(SimpleTestCase):
|
|||||||
def test_invalid(self):
|
def test_invalid(self):
|
||||||
invalid_passwords = [
|
invalid_passwords = [
|
||||||
(u'passwort', [
|
(u'passwort', [
|
||||||
u'The password must not contain the word \'passwort\'',
|
u'Das Passwort darf nicht die Zeichenfolge \'passwort\' enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'abcdDaVefgh', [
|
(u'abcdDaVefgh', [
|
||||||
u'The password must not contain the word \'dav\'',
|
u'Das Passwort darf nicht die Zeichenfolge \'dav\' enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'abcdsektIonefgh', [
|
(u'abcdsektIonefgh', [
|
||||||
u'The password must not contain the word \'sektion\'',
|
u'Das Passwort darf nicht die Zeichenfolge \'sektion\' enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'alpen12verein34KArlsruhE berge', [
|
(u'alpen12verein34KArlsruhE berge', [
|
||||||
u'The password must not contain the word \'karlsruhe\'',
|
u'Das Passwort darf nicht die Zeichenfolge \'karlsruhe\' enthalten.',
|
||||||
u'The password must not contain the word \'berge\'',
|
u'Das Passwort darf nicht die Zeichenfolge \'berge\' enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'heinzel@alpenverein-karlsruhe.de', [
|
(u'heinzel@alpenverein-karlsruhe.de', [
|
||||||
u'The password must not contain the word \'heinzel\'',
|
u'Das Passwort darf nicht die Zeichenfolge \'heinzel\' enthalten.',
|
||||||
u'The password must not contain the word \'alpenverein\'',
|
u'Das Passwort darf nicht die Zeichenfolge \'alpenverein\' enthalten.',
|
||||||
u'The password must not contain the word \'karlsruhe\'',
|
u'Das Passwort darf nicht die Zeichenfolge \'karlsruhe\' enthalten.',
|
||||||
]),
|
]),
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -140,66 +140,66 @@ class CharacterClassPasswordValidatorTestCase(SimpleTestCase):
|
|||||||
def test_invalid(self):
|
def test_invalid(self):
|
||||||
invalid_passwords = [
|
invalid_passwords = [
|
||||||
(u'', [
|
(u'', [
|
||||||
u'The password must contain at least 2 characters from a-z',
|
u'Das Passwort muss mindestens 2 Kleinbuchstaben enthalten.',
|
||||||
u'The password must contain at least 2 characters from A-Z',
|
u'Das Passwort muss mindestens 2 Großbuchstaben enthalten.',
|
||||||
u'The password must contain at least 2 digits from 0-9',
|
u'Das Passwort muss mindestens 2 Ziffern enthalten.',
|
||||||
u'The password must contain at least 2 non alpha numeric characters',
|
u'Das Passwort muss mindestens 2 Sonderzeichen enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'A+-', [
|
(u'A+-', [
|
||||||
u'The password must contain at least 2 characters from a-z',
|
u'Das Passwort muss mindestens 2 Kleinbuchstaben enthalten.',
|
||||||
u'The password must contain at least 2 characters from A-Z',
|
u'Das Passwort muss mindestens 2 Großbuchstaben enthalten.',
|
||||||
u'The password must contain at least 2 digits from 0-9',
|
u'Das Passwort muss mindestens 2 Ziffern enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'1234567890*', [
|
(u'1234567890*', [
|
||||||
u'The password must contain at least 2 characters from a-z',
|
u'Das Passwort muss mindestens 2 Kleinbuchstaben enthalten.',
|
||||||
u'The password must contain at least 2 characters from A-Z',
|
u'Das Passwort muss mindestens 2 Großbuchstaben enthalten.',
|
||||||
u'The password must contain at least 2 non alpha numeric characters',
|
u'Das Passwort muss mindestens 2 Sonderzeichen enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'34*/()', [
|
(u'34*/()', [
|
||||||
u'The password must contain at least 2 characters from a-z',
|
u'Das Passwort muss mindestens 2 Kleinbuchstaben enthalten.',
|
||||||
u'The password must contain at least 2 characters from A-Z',
|
u'Das Passwort muss mindestens 2 Großbuchstaben enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'AA', [
|
(u'AA', [
|
||||||
u'The password must contain at least 2 characters from a-z',
|
u'Das Passwort muss mindestens 2 Kleinbuchstaben enthalten.',
|
||||||
u'The password must contain at least 2 digits from 0-9',
|
u'Das Passwort muss mindestens 2 Ziffern enthalten.',
|
||||||
u'The password must contain at least 2 non alpha numeric characters',
|
u'Das Passwort muss mindestens 2 Sonderzeichen enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'CD0.,', [
|
(u'CD0.,', [
|
||||||
u'The password must contain at least 2 characters from a-z',
|
u'Das Passwort muss mindestens 2 Kleinbuchstaben enthalten.',
|
||||||
u'The password must contain at least 2 digits from 0-9',
|
u'Das Passwort muss mindestens 2 Ziffern enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'EF56', [
|
(u'EF56', [
|
||||||
u'The password must contain at least 2 characters from a-z',
|
u'Das Passwort muss mindestens 2 Kleinbuchstaben enthalten.',
|
||||||
u'The password must contain at least 2 non alpha numeric characters',
|
u'Das Passwort muss mindestens 2 Sonderzeichen enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'8GH?!8', [
|
(u'8GH?!8', [
|
||||||
u'The password must contain at least 2 characters from a-z',
|
u'Das Passwort muss mindestens 2 Kleinbuchstaben enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'bbX', [
|
(u'bbX', [
|
||||||
u'The password must contain at least 2 characters from A-Z',
|
u'Das Passwort muss mindestens 2 Großbuchstaben enthalten.',
|
||||||
u'The password must contain at least 2 digits from 0-9',
|
u'Das Passwort muss mindestens 2 Ziffern enthalten.',
|
||||||
u'The password must contain at least 2 non alpha numeric characters',
|
u'Das Passwort muss mindestens 2 Sonderzeichen enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'$cd%', [
|
(u'$cd%', [
|
||||||
u'The password must contain at least 2 characters from A-Z',
|
u'Das Passwort muss mindestens 2 Großbuchstaben enthalten.',
|
||||||
u'The password must contain at least 2 digits from 0-9',
|
u'Das Passwort muss mindestens 2 Ziffern enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'ef90', [
|
(u'ef90', [
|
||||||
u'The password must contain at least 2 characters from A-Z',
|
u'Das Passwort muss mindestens 2 Großbuchstaben enthalten.',
|
||||||
u'The password must contain at least 2 non alpha numeric characters',
|
u'Das Passwort muss mindestens 2 Sonderzeichen enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'1g=h3~', [
|
(u'1g=h3~', [
|
||||||
u'The password must contain at least 2 characters from A-Z',
|
u'Das Passwort muss mindestens 2 Großbuchstaben enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'Gi&jH', [
|
(u'Gi&jH', [
|
||||||
u'The password must contain at least 2 digits from 0-9',
|
u'Das Passwort muss mindestens 2 Ziffern enthalten.',
|
||||||
u'The password must contain at least 2 non alpha numeric characters',
|
u'Das Passwort muss mindestens 2 Sonderzeichen enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'IkK:i;', [
|
(u'IkK:i;', [
|
||||||
u'The password must contain at least 2 digits from 0-9',
|
u'Das Passwort muss mindestens 2 Ziffern enthalten.',
|
||||||
]),
|
]),
|
||||||
(u'mKn4L8', [
|
(u'mKn4L8', [
|
||||||
u'The password must contain at least 2 non alpha numeric characters',
|
u'Das Passwort muss mindestens 2 Sonderzeichen enthalten.',
|
||||||
]),
|
]),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from django.urls import reverse
|
|||||||
from ..forms import LoginForm, SetPasswordForm, CreateAndSendPasswordForm
|
from ..forms import LoginForm, SetPasswordForm, CreateAndSendPasswordForm
|
||||||
|
|
||||||
TEST_USERNAME = 'root@localhost'
|
TEST_USERNAME = 'root@localhost'
|
||||||
TEST_PASSWORD = u'me||ön 2'
|
TEST_PASSWORD = u'me||ön 21ABll'
|
||||||
TEST_EMAIL = TEST_USERNAME
|
TEST_EMAIL = TEST_USERNAME
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -56,15 +56,15 @@ class PasswordScoreValidator(object):
|
|||||||
score, used_classes = self._get_score(password, user=user)
|
score, used_classes = self._get_score(password, user=user)
|
||||||
|
|
||||||
if used_classes < self.min_classes:
|
if used_classes < self.min_classes:
|
||||||
raise ValidationError(_(u'The password must contain characters from at least %(min_classes)d'
|
raise ValidationError(_(u'Das Passwort muss Zeichen aus mindestens %(min_classes)d'
|
||||||
u' different character classes (i.e. lower, upper, digits, others).'),
|
u' verschiedenen Arten von Zeichen bestehen'
|
||||||
|
u' (d.h. Kleinbuchstaben, Großbuchstaben, Ziffern und Sonderzeichen).'),
|
||||||
code='too_few_classes',
|
code='too_few_classes',
|
||||||
params={'min_classes': self.min_classes})
|
params={'min_classes': self.min_classes})
|
||||||
|
|
||||||
if score < self.min_score:
|
if score < self.min_score:
|
||||||
raise ValidationError(_(u'The password is too simple. Use more characters'
|
raise ValidationError(_(u'Dieses Passwort ist zu einfach. Benutze mehr Zeichen'
|
||||||
u' and maybe use more different character classes'
|
u' und gegebenenfalls auch Großbuchstaben, Ziffern und Sonderzeichen.'),
|
||||||
u' (i.e. lower, upper, digits, others).'),
|
|
||||||
code='too_little_score')
|
code='too_little_score')
|
||||||
|
|
||||||
return score
|
return score
|
||||||
@@ -116,7 +116,7 @@ class CustomWordlistPasswordValidator(object):
|
|||||||
lower_pw = password.lower()
|
lower_pw = password.lower()
|
||||||
for word in self.words:
|
for word in self.words:
|
||||||
if word in lower_pw:
|
if word in lower_pw:
|
||||||
error = ValidationError(_(u'The password must not contain the word \'%(word)s\''),
|
error = ValidationError(_(u'Das Passwort darf nicht die Zeichenfolge \'%(word)s\' enthalten.'),
|
||||||
code='forbidden_word',
|
code='forbidden_word',
|
||||||
params={'word': word})
|
params={'word': word})
|
||||||
errors.append(error)
|
errors.append(error)
|
||||||
@@ -166,23 +166,23 @@ class CharacterClassPasswordValidator(object):
|
|||||||
def validate(self, password, user=None):
|
def validate(self, password, user=None):
|
||||||
errors = []
|
errors = []
|
||||||
if not self._is_enough_lower(password):
|
if not self._is_enough_lower(password):
|
||||||
error = ValidationError(_(u'The password must contain at least %(min_lower)d characters from a-z'),
|
error = ValidationError(_(u'Das Passwort muss mindestens %(min_lower)d Kleinbuchstaben enthalten.'),
|
||||||
code='too_few_lower_characters',
|
code='too_few_lower_characters',
|
||||||
params={'min_lower': self.minimum_lower})
|
params={'min_lower': self.minimum_lower})
|
||||||
errors.append(error)
|
errors.append(error)
|
||||||
if not self._is_enough_upper(password):
|
if not self._is_enough_upper(password):
|
||||||
error = ValidationError(_(u'The password must contain at least %(min_upper)d characters from A-Z'),
|
error = ValidationError(_(u'Das Passwort muss mindestens %(min_upper)d Großbuchstaben enthalten.'),
|
||||||
code='too_few_upper_characters',
|
code='too_few_upper_characters',
|
||||||
params={'min_upper': self.minimum_upper})
|
params={'min_upper': self.minimum_upper})
|
||||||
errors.append(error)
|
errors.append(error)
|
||||||
if not self._is_enough_digits(password):
|
if not self._is_enough_digits(password):
|
||||||
error = ValidationError(_(u'The password must contain at least %(min_digits)d digits from 0-9'),
|
error = ValidationError(_(u'Das Passwort muss mindestens %(min_digits)d Ziffern enthalten.'),
|
||||||
code='too_few_digits',
|
code='too_few_digits',
|
||||||
params={'min_digits': self.minimum_digits})
|
params={'min_digits': self.minimum_digits})
|
||||||
errors.append(error)
|
errors.append(error)
|
||||||
if not self._is_enough_others(password):
|
if not self._is_enough_others(password):
|
||||||
error = ValidationError(_(u'The password must contain at least %(min_others)d'
|
error = ValidationError(_(u'Das Passwort muss mindestens %(min_others)d'
|
||||||
u' non alpha numeric characters'),
|
u' Sonderzeichen enthalten.'),
|
||||||
code='too_few_other_characters',
|
code='too_few_other_characters',
|
||||||
params={'min_others': self.minimum_others})
|
params={'min_others': self.minimum_others})
|
||||||
errors.append(error)
|
errors.append(error)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
import logging
|
import logging
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
@@ -7,6 +8,7 @@ from django.contrib.auth.password_validation import validate_password
|
|||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.shortcuts import resolve_url
|
from django.shortcuts import resolve_url
|
||||||
from django.urls import reverse_lazy, reverse
|
from django.urls import reverse_lazy, reverse
|
||||||
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
|
|
||||||
@@ -29,11 +31,19 @@ class LoginView(auth_views.LoginView):
|
|||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
r = super(LoginView, self).form_valid(form)
|
r = super(LoginView, self).form_valid(form)
|
||||||
|
messages.success(self.request, _(u'Benutzer angemeldet: %(username)s') % {'username': form.get_user()})
|
||||||
try:
|
try:
|
||||||
validate_password(form.cleaned_data['password'])
|
validate_password(form.cleaned_data['password'])
|
||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
logger.warning(u'Weak password (%d): %s', self.request.user.pk, e)
|
logger.warning(u'Weak password (%d): %s', self.request.user.pk, e)
|
||||||
messages.success(self.request, _(u'Benutzer angemeldet: %(username)s') % {'username': form.get_user()})
|
message = u'<br />\n<p>\n'
|
||||||
|
message += u'Dein Passwort entspricht nicht mehr den aktuellen Passwortrichtlinien.<br />\n'
|
||||||
|
message += u'Bitte hilf uns die Daten deiner Teilnehmer zu schützen und ändere dein Passwort.<br />\n'
|
||||||
|
message += u'</p>\n'
|
||||||
|
message += u'<p>\n'
|
||||||
|
message += u'<a href="%(href)s">Passwort ändern</a>\n' % {'href': reverse('dav_auth:set_password')}
|
||||||
|
message += u'</p>\n<br />\n'
|
||||||
|
messages.warning(self.request, mark_safe(message))
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
@@ -76,7 +86,7 @@ class CreateAndSendPasswordView(generic.FormView):
|
|||||||
user_model = get_user_model()
|
user_model = get_user_model()
|
||||||
try:
|
try:
|
||||||
user = user_model.objects.get(username=username)
|
user = user_model.objects.get(username=username)
|
||||||
random_password = user_model.objects.make_random_password(length=12)
|
random_password = user_model.objects.make_random_password(length=32)
|
||||||
user.set_password(random_password)
|
user.set_password(random_password)
|
||||||
user.save()
|
user.save()
|
||||||
email = emails.PasswordSetEmail(user, random_password)
|
email = emails.PasswordSetEmail(user, random_password)
|
||||||
|
|||||||
@@ -52,6 +52,30 @@ DATABASES['default'] = {
|
|||||||
'NAME': os.path.join(BASE_VAR_DIR, 'db', 'devel.sqlite3'),
|
'NAME': os.path.join(BASE_VAR_DIR, 'db', 'devel.sqlite3'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||||
|
'OPTIONS': {
|
||||||
|
'min_length': 12,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'dav_auth.validators.PasswordScoreValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'dav_auth.validators.CustomWordlistPasswordValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
STATIC_ROOT = os.path.join(BASE_VAR_DIR, 'www', 'static')
|
STATIC_ROOT = os.path.join(BASE_VAR_DIR, 'www', 'static')
|
||||||
|
|
||||||
LANGUAGE_CODE = 'de'
|
LANGUAGE_CODE = 'de'
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from dav_auth.tests.generic import SeleniumAuthMixin
|
|||||||
from .generic import RoleMixin
|
from .generic import RoleMixin
|
||||||
|
|
||||||
TEST_TRAINER_EMAIL = 'trainer@localhost'
|
TEST_TRAINER_EMAIL = 'trainer@localhost'
|
||||||
TEST_PASSWORD = u'me||ön 2'
|
TEST_PASSWORD = u'me||ön 21ABll'
|
||||||
TEST_EVENT_DATA_S = {
|
TEST_EVENT_DATA_S = {
|
||||||
'mode': 'training',
|
'mode': 'training',
|
||||||
'sport': 'S',
|
'sport': 'S',
|
||||||
|
|||||||
Reference in New Issue
Block a user