From fcf8a0e221920baab063c915a4c43e3b77f909a9 Mon Sep 17 00:00:00 2001 From: Ali-D-Akbar Date: Wed, 14 Apr 2021 14:01:45 +0500 Subject: [PATCH] fix: allow staff or superuser to reset password from support tools --- .../user_authn/views/password_reset.py | 2 +- .../user_authn/views/tests/test_password.py | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/openedx/core/djangoapps/user_authn/views/password_reset.py b/openedx/core/djangoapps/user_authn/views/password_reset.py index 3a5b4e1a8a..93d3ebfbc1 100644 --- a/openedx/core/djangoapps/user_authn/views/password_reset.py +++ b/openedx/core/djangoapps/user_authn/views/password_reset.py @@ -594,7 +594,7 @@ def password_change_request_handler(request): """ user = request.user - if user.is_staff and user.is_superuser and request.POST.get('email_from_support_tools'): + if (user.is_staff or user.is_superuser) and request.POST.get('email_from_support_tools'): email = request.POST.get('email_from_support_tools') else: # Prefer logged-in user's email diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_password.py b/openedx/core/djangoapps/user_authn/views/tests/test_password.py index 6d694a5283..764a2178af 100644 --- a/openedx/core/djangoapps/user_authn/views/tests/test_password.py +++ b/openedx/core/djangoapps/user_authn/views/tests/test_password.py @@ -28,6 +28,7 @@ from openedx.core.djangoapps.user_api.accounts.tests.test_api import CreateAccou from openedx.core.djangoapps.user_api.errors import UserAPIInternalError, UserNotFound from openedx.core.djangoapps.user_authn.views.password_reset import request_password_change from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, skip_unless_lms +from common.djangoapps.student.tests.factories import UserFactory LOGGER_NAME = 'audit' User = get_user_model() # pylint:disable=invalid-name @@ -176,6 +177,36 @@ class TestPasswordChange(CreateAccountMixin, CacheIsolationTestCase): response_dict = json.loads(response.content.decode('utf-8')) assert response_dict['success'] + @ddt.data( + (True, True, OLD_EMAIL), + (True, False, OLD_EMAIL), + (False, True, OLD_EMAIL), + (False, False, 'edx@example.com'), + ) + @ddt.unpack + def test_password_change_from_support_tools(self, is_superuser, is_staff, reset_email): + """ + Request a password change from Support Tools while logged in from a staff/superuser + """ + self.client.logout() + UserFactory.create( + username='edx', + email='edx@example.com', + password='edx', + is_superuser=is_superuser, + is_staff=is_staff, + ) + self.client.login(username='edx', password='edx') + + response = self._change_password_from_support(email_from_support_tools=self.OLD_EMAIL) + assert response.status_code == 200 + + # Check that an email was sent + assert len(mail.outbox) == 1 + assert reset_email in mail.outbox[0].to + email_body = mail.outbox[0].body + assert email_body is not None + def test_password_change_failure(self): with patch( 'openedx.core.djangoapps.user_authn.views.password_reset.request_password_change', @@ -314,6 +345,15 @@ class TestPasswordChange(CreateAccountMixin, CacheIsolationTestCase): return self.client.post(path=reverse('password_change_request'), data=data) + def _change_password_from_support(self, email_from_support_tools=None): + """Request to change the user's password. """ + data = {} + + if email_from_support_tools: + data['email_from_support_tools'] = email_from_support_tools + + return self.client.post(path=reverse('password_change_request'), data=data) + def _create_dot_tokens(self, user=None): """Create dot access token for given user if user provided else for default user.""" if not user: