From 4663c85d96c79e76133af0be06793734fc037293 Mon Sep 17 00:00:00 2001 From: Troy Sankey Date: Wed, 4 Mar 2026 08:55:08 -0800 Subject: [PATCH 1/2] feat: replace enterprise username import in progress/views.py with pluggable_override Remove get_enterprise_learner_generic_name import. Add obfuscated_username function decorated with @pluggable_override('OVERRIDE_COURSE_HOME_PROGRESS_USERNAME') returning None by default. ENT-11572 --- lms/djangoapps/course_home_api/progress/views.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lms/djangoapps/course_home_api/progress/views.py b/lms/djangoapps/course_home_api/progress/views.py index 211f81d8ca5a..9169d6adca64 100644 --- a/lms/djangoapps/course_home_api/progress/views.py +++ b/lms/djangoapps/course_home_api/progress/views.py @@ -5,6 +5,7 @@ from django.contrib.auth import get_user_model from django.http.response import Http404 from edx_django_utils import monitoring as monitoring_utils +from edx_django_utils.plugins import pluggable_override from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication from edx_rest_framework_extensions.auth.session.authentication import SessionAuthenticationAllowInactiveUser from opaque_keys.edx.keys import CourseKey @@ -33,12 +34,23 @@ from openedx.core.lib.api.authentication import BearerAuthenticationAllowInactiveUser from openedx.features.content_type_gating.block_transformers import ContentTypeGateTransformer from openedx.features.course_duration_limits.access import get_access_expiration_data -from openedx.features.enterprise_support.utils import get_enterprise_learner_generic_name from xmodule.modulestore.django import modulestore User = get_user_model() +@pluggable_override('OVERRIDE_COURSE_HOME_PROGRESS_USERNAME') +def obfuscated_username(request, student): + """ + Return an obfuscated username for the student, or None. + + This function can be overridden by an installed plugin via the + OVERRIDE_COURSE_HOME_PROGRESS_USERNAME setting to return a generic name + for learners who should not have their real username exposed. + """ + return None + + class ProgressTabView(RetrieveAPIView): """ **Use Cases** @@ -202,7 +214,7 @@ def get(self, request, *args, **kwargs): # pylint: disable=too-many-statement student = self._get_student_user(request, course_key, student_id, requester_has_staff_access) learner_has_staff_access = bool(has_access(student, 'staff', course_key)) - username = get_enterprise_learner_generic_name(request) or student.username + username = obfuscated_username(request, student) or student.username course = get_course_or_403(student, 'load', course_key, check_if_enrolled=False) From afbafaaa0610079474163291cd7fc8d50d6a3098 Mon Sep 17 00:00:00 2001 From: Marlon Keating Date: Mon, 4 May 2026 14:08:08 +0000 Subject: [PATCH 2/2] docs: clarify obfuscated_username behavior --- lms/djangoapps/course_home_api/progress/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lms/djangoapps/course_home_api/progress/views.py b/lms/djangoapps/course_home_api/progress/views.py index 9169d6adca64..577392dc9527 100644 --- a/lms/djangoapps/course_home_api/progress/views.py +++ b/lms/djangoapps/course_home_api/progress/views.py @@ -42,7 +42,8 @@ @pluggable_override('OVERRIDE_COURSE_HOME_PROGRESS_USERNAME') def obfuscated_username(request, student): """ - Return an obfuscated username for the student, or None. + Return an obfuscated username for the student, or None (indicating student's + real name should be used). This function can be overridden by an installed plugin via the OVERRIDE_COURSE_HOME_PROGRESS_USERNAME setting to return a generic name