Improve password complexity messaging
Send password form instructions that include password complexity and also send error messages back that include all parts of the complexity instead of single parts at a time. And clean up phrasing to be more consistent.
This commit is contained in:
committed by
Michael Terry
parent
795dda47d8
commit
a576d682ff
@@ -15,7 +15,9 @@ from openedx.core.djangoapps.user_api.helpers import FormDescription
|
||||
from openedx.features.enterprise_support.api import enterprise_customer_for_request
|
||||
from student.forms import get_registration_extension_form
|
||||
from student.models import UserProfile
|
||||
from util.password_policy_validators import password_max_length, password_min_length
|
||||
from util.password_policy_validators import (
|
||||
password_complexity, password_instructions, password_max_length, password_min_length
|
||||
)
|
||||
|
||||
|
||||
def get_password_reset_form():
|
||||
@@ -415,23 +417,21 @@ class RegistrationFormFactory(object):
|
||||
# meant to hold the user's password.
|
||||
password_label = _(u"Password")
|
||||
|
||||
restrictions = {}
|
||||
|
||||
if settings.FEATURES.get('ENFORCE_PASSWORD_POLICY', False):
|
||||
complexities = getattr(settings, 'PASSWORD_COMPLEXITY', {})
|
||||
for key, value in complexities.iteritems():
|
||||
api_key = key.lower().replace(' ', '_')
|
||||
restrictions[api_key] = value
|
||||
|
||||
restrictions.update({
|
||||
restrictions = {
|
||||
"min_length": password_min_length(),
|
||||
"max_length": password_max_length(),
|
||||
})
|
||||
}
|
||||
|
||||
complexities = password_complexity()
|
||||
for key, value in complexities.iteritems():
|
||||
api_key = key.lower().replace(' ', '_')
|
||||
restrictions[api_key] = value
|
||||
|
||||
form_desc.add_field(
|
||||
"password",
|
||||
label=password_label,
|
||||
field_type="password",
|
||||
instructions=password_instructions(),
|
||||
restrictions=restrictions,
|
||||
required=required
|
||||
)
|
||||
|
||||
@@ -1055,6 +1055,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase):
|
||||
u"type": u"password",
|
||||
u"required": True,
|
||||
u"label": u"Password",
|
||||
u"instructions": u'Your password must contain at least {} characters.'.format(password_min_length()),
|
||||
u"restrictions": {
|
||||
'min_length': password_min_length(),
|
||||
'max_length': password_max_length(),
|
||||
@@ -1072,6 +1073,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase):
|
||||
{
|
||||
u'name': u'password',
|
||||
u'label': u'Password',
|
||||
u'instructions': u'Your password must contain at least {} characters.'.format(password_min_length()),
|
||||
u'restrictions': {
|
||||
'min_length': password_min_length(),
|
||||
'max_length': password_max_length(),
|
||||
@@ -1081,11 +1083,14 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase):
|
||||
|
||||
# Now with an enabled password policy
|
||||
with mock.patch.dict(settings.FEATURES, {'ENFORCE_PASSWORD_POLICY': True}):
|
||||
msg = u'Your password must contain at least {} characters, including '\
|
||||
u'3 uppercase letters & 1 symbol.'.format(password_min_length())
|
||||
self._assert_reg_field(
|
||||
no_extra_fields_setting,
|
||||
{
|
||||
u'name': u'password',
|
||||
u'label': u'Password',
|
||||
u'instructions': msg,
|
||||
u'restrictions': {
|
||||
'min_length': password_min_length(),
|
||||
'max_length': password_max_length(),
|
||||
|
||||
@@ -172,7 +172,7 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase):
|
||||
)
|
||||
|
||||
def test_password_empty_validation_decision(self):
|
||||
msg = u'Password: Invalid Length (must be {0} characters or more)'.format(password_min_length())
|
||||
msg = u'Enter a password with at least {0} characters.'.format(password_min_length())
|
||||
self.assertValidationDecision(
|
||||
{'password': ''},
|
||||
{"password": msg}
|
||||
@@ -180,7 +180,7 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase):
|
||||
|
||||
def test_password_bad_min_length_validation_decision(self):
|
||||
password = 'p' * (password_min_length() - 1)
|
||||
msg = u'Password: Invalid Length (must be {0} characters or more)'.format(password_min_length())
|
||||
msg = u'Enter a password with at least {0} characters.'.format(password_min_length())
|
||||
self.assertValidationDecision(
|
||||
{'password': password},
|
||||
{"password": msg}
|
||||
@@ -188,7 +188,7 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase):
|
||||
|
||||
def test_password_bad_max_length_validation_decision(self):
|
||||
password = 'p' * (password_max_length() + 1)
|
||||
msg = u'Password: Invalid Length (must be {0} characters or fewer)'.format(password_max_length())
|
||||
msg = u'Enter a password with at most {0} characters.'.format(password_max_length())
|
||||
self.assertValidationDecision(
|
||||
{'password': password},
|
||||
{"password": msg}
|
||||
@@ -197,5 +197,5 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase):
|
||||
def test_password_equals_username_validation_decision(self):
|
||||
self.assertValidationDecision(
|
||||
{"username": "somephrase", "password": "somephrase"},
|
||||
{"username": "", "password": u"Password cannot be the same as the username"}
|
||||
{"username": "", "password": u"Password cannot be the same as the username."}
|
||||
)
|
||||
|
||||
@@ -57,7 +57,7 @@ class RegistrationValidationView(APIView):
|
||||
>>> {
|
||||
>>> "validation_decisions": {
|
||||
>>> "username": "",
|
||||
>>> "password": "Password cannot be the same as the username"
|
||||
>>> "password": "Password cannot be the same as the username."
|
||||
>>> }
|
||||
>>> }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user