0001-misc-use-a-template-for-NewPasswordInput-63831.patch
src/authentic2/forms/fields.py | ||
---|---|---|
31 | 31 |
PasswordInput, |
32 | 32 |
ProfileImageInput, |
33 | 33 |
) |
34 |
from authentic2.passwords import password_help_text, validate_password
|
|
34 |
from authentic2.passwords import validate_password |
|
35 | 35 |
from authentic2.validators import email_validator |
36 | 36 | |
37 | 37 | |
... | ... | |
43 | 43 |
widget = NewPasswordInput |
44 | 44 |
default_validators = [validate_password] |
45 | 45 | |
46 |
def __init__(self, *args, **kwargs): |
|
47 |
kwargs['help_text'] = password_help_text() |
|
48 |
super().__init__(*args, **kwargs) |
|
49 | ||
50 | 46 | |
51 | 47 |
class CheckPasswordField(CharField): |
52 | 48 |
widget = CheckPasswordInput |
src/authentic2/forms/widgets.py | ||
---|---|---|
41 | 41 |
from gadjo.templatetags.gadjo import xstatic |
42 | 42 | |
43 | 43 |
from authentic2 import app_settings |
44 |
from authentic2.passwords import get_password_checker |
|
44 | 45 | |
45 | 46 |
DATE_FORMAT_JS_PY_MAPPING = { |
46 | 47 |
'P': '%p', |
... | ... | |
270 | 271 | |
271 | 272 | |
272 | 273 |
class NewPasswordInput(PasswordInput): |
274 |
template_name = 'authentic2/widgets/new_password.html' |
|
275 | ||
276 |
def get_context(self, *args, **kwargs): |
|
277 |
context = super().get_context(*args, **kwargs) |
|
278 |
password_checker = get_password_checker() |
|
279 |
checks = list(password_checker('')) |
|
280 |
context['checks'] = checks |
|
281 |
return context |
|
282 | ||
273 | 283 |
def render(self, name, value, attrs=None, renderer=None): |
274 | 284 |
if attrs is None: |
275 | 285 |
attrs = {} |
src/authentic2/passwords.py | ||
---|---|---|
20 | 20 |
import string |
21 | 21 | |
22 | 22 |
from django.core.exceptions import ValidationError |
23 |
from django.utils.functional import lazy |
|
24 | 23 |
from django.utils.module_loading import import_string |
25 | 24 |
from django.utils.translation import ugettext as _ |
26 | 25 |
from zxcvbn import zxcvbn |
... | ... | |
127 | 126 | |
128 | 127 | |
129 | 128 |
def validate_password(password): |
130 |
error = password_help_text(password, only_errors=True) |
|
131 |
if error: |
|
132 |
raise ValidationError(_('This password is not accepted.')) |
|
133 | ||
134 | ||
135 |
def password_help_text(password='', only_errors=False): |
|
136 | 129 |
password_checker = get_password_checker() |
137 |
criteria = [check.label for check in password_checker(password) if not (only_errors and check.result)] |
|
138 |
if criteria: |
|
139 |
html_criteria = ['<span class="a2-password-policy-rule">%s</span>' % criter for criter in criteria] |
|
140 |
return _( |
|
141 |
'In order to create a secure password, please use at least: <span' |
|
142 |
' class="a2-password-policy-container">%s</span>' |
|
143 |
) % ''.join(html_criteria) |
|
144 |
else: |
|
145 |
return '' |
|
146 | ||
147 | ||
148 |
password_help_text = lazy(password_help_text, str) |
|
130 |
errors = [not check.result for check in password_checker(password)] |
|
131 |
if any(errors): |
|
132 |
raise ValidationError(_('This password is not accepted.')) |
src/authentic2/static/authentic2/css/password.scss | ||
---|---|---|
1 |
.a2-password-policy-hint { |
|
2 |
display: block; |
|
3 |
font-size: 80%; |
|
4 |
} |
|
5 | ||
1 | 6 |
/* position span to show last char */ |
2 | 7 |
.a2-password-show-last-char { |
3 | 8 |
text-align: center; |
src/authentic2/static/authentic2/js/password.js | ||
---|---|---|
3 | 3 |
$(function () { |
4 | 4 |
function check_equality() { |
5 | 5 |
setTimeout(function () { |
6 |
var $help_text = $input2.parent().find('.hint'); |
|
6 |
var $help_text = $input2.parent().find('.a2-password-policy-hint');
|
|
7 | 7 |
var password1 = $input1.val(); |
8 | 8 |
var password2 = $input2.val(); |
9 | 9 | |
... | ... | |
36 | 36 |
} |
37 | 37 |
function get_validation($input) { |
38 | 38 |
var password = $input.val(); |
39 |
var $help_text = $input.parent().find('.hint'); |
|
39 |
var $help_text = $input.parent().find('.a2-password-policy-hint');
|
|
40 | 40 |
var $policyContainer = $help_text.find('.a2-password-policy-container'); |
41 | 41 |
$.ajax({ |
42 | 42 |
method: 'POST', |
src/authentic2/templates/authentic2/widgets/new_password.html | ||
---|---|---|
1 |
{% load i18n %} |
|
2 |
{% include "django/forms/widgets/input.html" %} |
|
3 |
<div class="a2-password-policy-hint"> |
|
4 |
{% trans "In order to create a secure password, please use at least :" %} |
|
5 |
<div class="a2-password-policy-container"> |
|
6 |
{% for check in checks %} |
|
7 |
<span class="a2-password-policy-rule">{{ check.label }}</span> |
|
8 |
{% endfor %} |
|
9 |
</div> |
|
10 |
</div> |
src/authentic2/validators.py | ||
---|---|---|
29 | 29 |
from . import app_settings |
30 | 30 | |
31 | 31 |
# keep those symbols here for retrocompatibility |
32 |
from .passwords import password_help_text, validate_password # pylint: disable=unused-import
|
|
32 |
from .passwords import validate_password # pylint: disable=unused-import |
|
33 | 33 | |
34 | 34 | |
35 | 35 |
# copied from http://www.djangotips.com/real-email-validation |
36 |
- |