From abc42ec2362cef11b8d0ecb83eab07e5bd09e5e8 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Thu, 15 Mar 2018 15:58:21 -0400 Subject: [PATCH] Send password requirements to mobile We have a registration endpoint that sends all the information the mobile app needs to render a form, including password requirements. But it wasn't sending complexity information before (e.g. 1 uppercase letter). Now it does! --- openedx/core/djangoapps/user_api/api.py | 18 +++++++--- openedx/core/djangoapps/user_api/helpers.py | 3 +- .../djangoapps/user_api/tests/test_views.py | 33 +++++++++++++++++++ 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/openedx/core/djangoapps/user_api/api.py b/openedx/core/djangoapps/user_api/api.py index e8f16f58b2..b5a79e0579 100644 --- a/openedx/core/djangoapps/user_api/api.py +++ b/openedx/core/djangoapps/user_api/api.py @@ -415,14 +415,24 @@ 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({ + "min_length": password_min_length(), + "max_length": password_max_length(), + }) + form_desc.add_field( "password", label=password_label, field_type="password", - restrictions={ - "min_length": password_min_length(), - "max_length": password_max_length(), - }, + restrictions=restrictions, required=required ) diff --git a/openedx/core/djangoapps/user_api/helpers.py b/openedx/core/djangoapps/user_api/helpers.py index 182bba5546..61bcc4f56b 100644 --- a/openedx/core/djangoapps/user_api/helpers.py +++ b/openedx/core/djangoapps/user_api/helpers.py @@ -125,7 +125,8 @@ class FormDescription(object): ALLOWED_RESTRICTIONS = { "text": ["min_length", "max_length"], - "password": ["min_length", "max_length"], + "password": ["min_length", "max_length", "upper", "lower", "digits", "punctuation", "non_ascii", "words", + "numeric", "alphabetic"], "email": ["min_length", "max_length", "readonly"], } diff --git a/openedx/core/djangoapps/user_api/tests/test_views.py b/openedx/core/djangoapps/user_api/tests/test_views.py index ffc1a58db0..7fc3267d81 100644 --- a/openedx/core/djangoapps/user_api/tests/test_views.py +++ b/openedx/core/djangoapps/user_api/tests/test_views.py @@ -1062,6 +1062,39 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): } ) + @override_settings(PASSWORD_COMPLEXITY={'NON ASCII': 1, 'UPPER': 3}) + def test_register_form_password_complexity(self): + no_extra_fields_setting = {} + + # Without enabling password policy + self._assert_reg_field( + no_extra_fields_setting, + { + u'name': u'password', + u'label': u'Password', + u'restrictions': { + 'min_length': password_min_length(), + 'max_length': password_max_length(), + }, + } + ) + + # Now with an enabled password policy + with mock.patch.dict(settings.FEATURES, {'ENFORCE_PASSWORD_POLICY': True}): + self._assert_reg_field( + no_extra_fields_setting, + { + u'name': u'password', + u'label': u'Password', + u'restrictions': { + 'min_length': password_min_length(), + 'max_length': password_max_length(), + 'non_ascii': 1, + 'upper': 3, + }, + } + ) + @override_settings(REGISTRATION_EXTENSION_FORM='openedx.core.djangoapps.user_api.tests.test_helpers.TestCaseForm') def test_extension_form_fields(self): no_extra_fields_setting = {}