From 39de23c666d1a6a6313129709ea71832ef12f71b Mon Sep 17 00:00:00 2001 From: Samuel Walladge Date: Wed, 11 Sep 2019 10:22:47 +0930 Subject: [PATCH] Add flag to enable password change form in admin This was previously disabled because changing another user's password is both not usually recommended and bypasses password policy. Here, we add a feature flag (`ENABLE_CHANGE_USER_PASSWORD_ADMIN`) to allow re-enabling this password change form. This allows continued use of this functionality by clients that require it. --- cms/envs/common.py | 13 +++++++++++++ cms/urls.py | 3 ++- common/djangoapps/student/admin.py | 19 ++++++++++++------- lms/envs/common.py | 13 +++++++++++++ lms/urls.py | 12 +++++++++--- 5 files changed, 49 insertions(+), 11 deletions(-) diff --git a/cms/envs/common.py b/cms/envs/common.py index c04304ad7b..a3b10000a2 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -329,6 +329,19 @@ FEATURES = { 'SHOW_FOOTER_LANGUAGE_SELECTOR': False, 'ENABLE_ENROLLMENT_RESET': False, 'DISABLE_MOBILE_COURSE_AVAILABLE': False, + + # .. toggle_name: ENABLE_CHANGE_USER_PASSWORD_ADMIN + # .. toggle_implementation: DjangoSetting + # .. toggle_default: False + # .. toggle_description: Set to True to enable changing a user password through django admin. This is disabled by default because enabling allows a method to bypass password policy. + # .. toggle_category: admin + # .. toggle_use_cases: open_edx + # .. toggle_creation_date: 2020-02-21 + # .. toggle_expiration_date: None + # .. toggle_tickets: 'https://github.com/edx/edx-platform/pull/21616' + # .. toggle_status: supported + # .. toggle_warnings: None + 'ENABLE_CHANGE_USER_PASSWORD_ADMIN': False, } ENABLE_JASMINE = False diff --git a/cms/urls.py b/cms/urls.py index 6326e953d7..76a739d3e4 100644 --- a/cms/urls.py +++ b/cms/urls.py @@ -215,8 +215,9 @@ if settings.FEATURES.get('ENABLE_SERVICE_STATUS'): # The password pages in the admin tool are disabled so that all password # changes go through our user portal and follow complexity requirements. +if not settings.FEATURES.get('ENABLE_CHANGE_USER_PASSWORD_ADMIN'): + urlpatterns.append(url(r'^admin/auth/user/\d+/password/$', handler404)) urlpatterns.append(url(r'^admin/password_change/$', handler404)) -urlpatterns.append(url(r'^admin/auth/user/\d+/password/$', handler404)) urlpatterns.append(url(r'^admin/', admin.site.urls)) # enable entrance exams diff --git a/common/djangoapps/student/admin.py b/common/djangoapps/student/admin.py index 2d536e749c..55e3407eba 100644 --- a/common/djangoapps/student/admin.py +++ b/common/djangoapps/student/admin.py @@ -5,6 +5,7 @@ from functools import wraps from config_models.admin import ConfigurationModelAdmin from django import forms +from django.conf import settings from django.contrib import admin from django.contrib.admin.sites import NotRegistered from django.contrib.admin.utils import unquote @@ -289,13 +290,17 @@ class UserChangeForm(BaseUserChangeForm): Override the default UserChangeForm such that the password field does not contain a link to a 'change password' form. """ - password = ReadOnlyPasswordHashField( - label=_("Password"), - help_text=_( - "Raw passwords are not stored, so there is no way to see this " - "user's password." - ), - ) + def __init__(self, *args, **kwargs): + super(UserChangeForm, self).__init__(*args, **kwargs) + + if not settings.FEATURES.get('ENABLE_CHANGE_USER_PASSWORD_ADMIN'): + self.fields["password"] = ReadOnlyPasswordHashField( + label=_("Password"), + help_text=_( + "Raw passwords are not stored, so there is no way to see this " + "user's password." + ), + ) class UserAdmin(BaseUserAdmin): diff --git a/lms/envs/common.py b/lms/envs/common.py index 514480309a..6f3b4ed5b2 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -403,6 +403,19 @@ FEATURES = { # Enable feature to remove enrollments and users. Used to reset state of master's integration environments 'ENABLE_ENROLLMENT_RESET': False, 'DISABLE_MOBILE_COURSE_AVAILABLE': False, + + # .. toggle_name: ENABLE_CHANGE_USER_PASSWORD_ADMIN + # .. toggle_implementation: DjangoSetting + # .. toggle_default: False + # .. toggle_description: Set to True to enable changing a user password through django admin. This is disabled by default because enabling allows a method to bypass password policy. + # .. toggle_category: admin + # .. toggle_use_cases: open_edx + # .. toggle_creation_date: 2020-02-21 + # .. toggle_expiration_date: None + # .. toggle_tickets: 'https://github.com/edx/edx-platform/pull/21616' + # .. toggle_status: supported + # .. toggle_warnings: None + 'ENABLE_CHANGE_USER_PASSWORD_ADMIN': False, } # Settings for the course reviews tool template and identification key, set either to None to disable course reviews diff --git a/lms/urls.py b/lms/urls.py index 2de79115c4..32aa6b6708 100644 --- a/lms/urls.py +++ b/lms/urls.py @@ -773,11 +773,17 @@ if settings.FEATURES.get('ENABLE_STUDENT_HISTORY_VIEW'): if settings.DEBUG or settings.FEATURES.get('ENABLE_DJANGO_ADMIN_SITE'): # Jasmine and admin + + # The password pages in the admin tool are disabled so that all password + # changes go through our user portal and follow complexity requirements. + # The form to change another user's password is conditionally enabled + # for backwards compatibility. + if not settings.FEATURES.get('ENABLE_CHANGE_USER_PASSWORD_ADMIN'): + urlpatterns += [ + url(r'^admin/auth/user/\d+/password/$', handler404), + ] urlpatterns += [ - # The password pages in the admin tool are disabled so that all password - # changes go through our user portal and follow complexity requirements. url(r'^admin/password_change/$', handler404), - url(r'^admin/auth/user/\d+/password/$', handler404), # We are enforcing users to login through third party auth in site's # login page so we are disabling the admin panel's login page. url(r'^admin/login/$', redirect_to_lms_login),