1 |
1 |
from __future__ import unicode_literals
|
2 |
2 |
import string
|
3 |
3 |
import re
|
|
4 |
import six
|
4 |
5 |
|
5 |
6 |
import smtplib
|
6 |
7 |
|
7 |
|
from django.utils.translation import ugettext_lazy as _
|
|
8 |
from django.utils.translation import ugettext_lazy as _, ugettext
|
8 |
9 |
from django.utils.encoding import force_text
|
9 |
10 |
from django.core.exceptions import ValidationError
|
|
11 |
from django.utils.functional import lazy
|
10 |
12 |
|
11 |
13 |
import socket
|
12 |
14 |
import dns.resolver
|
13 |
15 |
import dns.exception
|
14 |
16 |
|
15 |
17 |
from . import app_settings
|
16 |
18 |
|
17 |
19 |
# copied from http://www.djangotips.com/real-email-validation
|
... | ... | |
78 |
80 |
email_validator = EmailValidator()
|
79 |
81 |
|
80 |
82 |
def validate_password(password):
|
81 |
83 |
password_set = set(password)
|
82 |
84 |
digits = set(string.digits)
|
83 |
85 |
lower = set(string.lowercase)
|
84 |
86 |
upper = set(string.uppercase)
|
85 |
87 |
punc = set(string.punctuation)
|
|
88 |
errors = []
|
86 |
89 |
|
87 |
90 |
if not password:
|
88 |
91 |
return
|
89 |
92 |
min_len = app_settings.A2_PASSWORD_POLICY_MIN_LENGTH
|
90 |
93 |
if len(password) < min_len:
|
91 |
|
raise ValidationError(_('password must contain at least %d '
|
92 |
|
'characters') % min_len)
|
|
94 |
errors.append(ValidationError(_('password must contain at least %d '
|
|
95 |
'characters') % min_len))
|
93 |
96 |
|
94 |
97 |
class_count = 0
|
95 |
98 |
for cls in (digits, lower, upper, punc):
|
96 |
99 |
if not password_set.isdisjoint(cls):
|
97 |
100 |
class_count += 1
|
98 |
101 |
min_class_count = app_settings.A2_PASSWORD_POLICY_MIN_CLASSES
|
99 |
102 |
if class_count < min_class_count:
|
100 |
|
raise ValidationError(_('password must contain characters '
|
|
103 |
errors.append(ValidationError(_('password must contain characters '
|
101 |
104 |
'from at least %d classes among: lowercase letters, '
|
102 |
|
'uppercase letters, digits, and punctuations') % min_class_count)
|
|
105 |
'uppercase letters, digits, and punctuations') % min_class_count))
|
103 |
106 |
if app_settings.A2_PASSWORD_POLICY_REGEX:
|
104 |
107 |
if not re.match(app_settings.A2_PASSWORD_POLICY_REGEX, password):
|
105 |
108 |
msg = app_settings.A2_PASSWORD_POLICY_REGEX_ERROR_MSG
|
106 |
109 |
msg = msg or _('your password dit not match the regular expession %s') % app_settings.A2_PASSWORD_POLICY_REGEX
|
107 |
|
raise ValidationError(msg)
|
|
110 |
errors.append(ValidationError(msg))
|
|
111 |
if errors:
|
|
112 |
raise ValidationError(errors)
|
|
113 |
|
|
114 |
def __password_help_text_helper():
|
|
115 |
if app_settings.A2_PASSWORD_POLICY_MIN_LENGTH:
|
|
116 |
yield ugettext('Your password must contain at least %(min_length)d characters.') % {'min_length': app_settings.A2_PASSWORD_POLICY_MIN_LENGTH}
|
|
117 |
if app_settings.A2_PASSWORD_POLICY_MIN_CLASSES:
|
|
118 |
yield ugettext('Your password must contain characters from at least %(min_classes)d '
|
|
119 |
'classes among: lowercase letters, uppercase letters, digits, '
|
|
120 |
'and punctuations') % {'min_classes': app_settings.A2_PASSWORD_POLICY_MIN_CLASSES}
|
|
121 |
if app_settings.A2_PASSWORD_POLICY_REGEX:
|
|
122 |
yield ugettext(app_settings.A2_PASSWORD_POLICY_REGEX_ERROR_MSG) or \
|
|
123 |
ugettext('Your password must match the regular expression: '
|
|
124 |
'%(regexp)s, please change this message using the '
|
|
125 |
'A2_PASSWORD_POLICY_REGEX_ERROR_MSG setting.') % \
|
|
126 |
{'regexp': app_settings.A2_PASSWORD_POLICY_REGEX}
|
|
127 |
|
|
128 |
def password_help_text():
|
|
129 |
return ' '.join(__password_help_text_helper())
|
|
130 |
|
|
131 |
password_help_text = lazy(password_help_text, six.text_type)
|
108 |
|
-
|