From 294ce53d6750c4eabd6e0c636005ab715a748b15 Mon Sep 17 00:00:00 2001 From: Haftamu Kebede <54979169+haftamuk@users.noreply.github.com> Date: Wed, 17 Jun 2026 16:54:23 +0300 Subject: [PATCH 1/2] feat: Custom roles added to enable course content search in studio search bar eSHEInstructorRole.ROLE, and TeachingAssistantRole.ROLEEnabling custom roles added to the studio course content search function to allow users utilize the service. --- openedx/core/djangoapps/content/search/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openedx/core/djangoapps/content/search/models.py b/openedx/core/djangoapps/content/search/models.py index 6fa53ef17b34..faed06866678 100644 --- a/openedx/core/djangoapps/content/search/models.py +++ b/openedx/core/djangoapps/content/search/models.py @@ -8,7 +8,7 @@ from rest_framework.request import Request from common.djangoapps.student.role_helpers import get_course_roles -from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRole +from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRole, eSHEInstructorRole, TeachingAssistantRole from openedx.core.djangoapps.content_libraries.api import get_libraries_for_user @@ -48,7 +48,7 @@ def get_access_ids_for_request(request: Request, omit_orgs: list[str] = None) -> role.course_id for role in course_roles if ( - role.role in [CourseInstructorRole.ROLE, CourseStaffRole.ROLE] + role.role in [eSHEInstructorRole.ROLE, TeachingAssistantRole.ROLE, CourseInstructorRole.ROLE, CourseStaffRole.ROLE] and role.org not in omit_orgs ) ]) From 6646dfddf5110d8c93abade908ed0f002d8ccc9e Mon Sep 17 00:00:00 2001 From: Haftamu Kebede <54979169+haftamuk@users.noreply.github.com> Date: Thu, 18 Jun 2026 05:55:44 +0300 Subject: [PATCH 2/2] fix: course listing and course detail pages are allowed for eSHE custom roles --- cms/djangoapps/contentstore/views/course.py | 6 +++++- common/djangoapps/student/auth.py | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index deeb4a4ee2fe..de9e39db57cb 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -53,6 +53,8 @@ GlobalStaff, UserBasedRole, OrgStaffRole, + eSHEInstructorRole, + TeachingAssistantRole, strict_role_checking, ) from common.djangoapps.util.json_request import JsonResponse, JsonResponseBadRequest, expect_json @@ -537,7 +539,9 @@ def filter_ccx(course_access): with strict_role_checking(): staff_courses = UserBasedRole(request.user, CourseStaffRole.ROLE).courses_with_role() - all_courses = list(filter(filter_ccx, instructor_courses | staff_courses)) + eshe_instructor_courses = UserBasedRole(request.user, eSHEInstructorRole.ROLE).courses_with_role() + ta_courses = UserBasedRole(request.user, TeachingAssistantRole.ROLE).courses_with_role() + all_courses = list(filter(filter_ccx, instructor_courses | staff_courses | eshe_instructor_courses | ta_courses)) courses_list = [] course_keys = {} diff --git a/common/djangoapps/student/auth.py b/common/djangoapps/student/auth.py index 047f0174a062..c8f9b0b0f362 100644 --- a/common/djangoapps/student/auth.py +++ b/common/djangoapps/student/auth.py @@ -24,6 +24,8 @@ OrgInstructorRole, OrgLibraryUserRole, OrgStaffRole, + eSHEInstructorRole, + TeachingAssistantRole, strict_role_checking, ) @@ -100,6 +102,14 @@ def get_user_permissions(user, course_key, org=None, service_variant=None): return all_perms if course_key and user_has_role(user, CourseInstructorRole(course_key)): return all_perms + + # Allow custom eSHE roles to access course detail in studio + # We have offered all permissions equivalent to Staff user + # This is to demonstrate how the custom roles can be elevated, NOT PRODUCTION READY + if course_key: + if eSHEInstructorRole(course_key).has_user(user) or TeachingAssistantRole(course_key).has_user(user): + return STUDIO_EDIT_ROLES | STUDIO_VIEW_USERS | STUDIO_EDIT_CONTENT | STUDIO_VIEW_CONTENT + # HACK: Limited Staff should not have studio read access. However, since many LMS views depend on the # `has_course_author_access` check and `course_author_access_required` decorator, we have to allow write access # by returning STUDIO_EDIT_CONTENT, if the request is made from LMS, until the permissions become more granular.