Skip to content

fix: Reapply CourseLimitedStaffRole update and add eSHE Instructor permissions#851

Open
viadanna wants to merge 2 commits into
viadanna/teak/bump-edxvalfrom
viadanna/fix-eshe-role
Open

fix: Reapply CourseLimitedStaffRole update and add eSHE Instructor permissions#851
viadanna wants to merge 2 commits into
viadanna/teak/bump-edxvalfrom
viadanna/fix-eshe-role

Conversation

@viadanna

Copy link
Copy Markdown
Member

Description

This PR reapplies the CourseLimitedStaffRole security fix changes and adds the necessary permissions for the eSHE Instructor role.

Supporting information

Testing instructions

  1. Create a test user and course.
  2. Add the user as an eSHE Instructor to the course.
  3. Log in to Studio with the test user and check the course shows in the list.
  4. Confirm the test user can also see the course outline and make changes.
  5. Verify the test user has access to the course's Gradebook.

@viadanna viadanna requested a review from kaustavb12 July 13, 2026 17:07
@viadanna viadanna self-assigned this Jul 13, 2026
Copilot AI review requested due to automatic review settings July 13, 2026 17:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens Studio authorization around CourseLimitedStaffRole (including the org-wide “admin-created row” edge case) and extends Studio access to the eSHEInstructorRole by explicitly including it in Studio permission checks and course listings.

Changes:

  • Adds regression tests to ensure course-limited staff cannot list or access courses in Studio (course-level and org-level rows).
  • Updates Studio permission computation to avoid treating derived staff roles as explicit staff, and adds an explicit eSHE instructor permission path.
  • Updates Studio course listing (group-reversal path) to include eSHE instructor courses while excluding inherited/derived roles from the generic staff query.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 8 comments.

File Description
common/djangoapps/student/tests/test_authz.py Adds coverage for org-level limited_staff rows not granting Studio access in CMS.
common/djangoapps/student/auth.py Uses strict role checking for explicit staff detection and adds explicit eSHE instructor Studio permissions.
cms/djangoapps/contentstore/views/course.py Applies strict role checking to staff course listing and unions in eSHE instructor courses.
cms/djangoapps/contentstore/tests/test_course_listing.py Adds course listing tests ensuring (org) limited staff cannot see courses in Studio.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +125 to 126
if course_key and user_has_role(user, eSHEInstructorRole(course_key)):
return STUDIO_VIEW_USERS | STUDIO_EDIT_CONTENT | STUDIO_VIEW_CONTENT
Comment on lines +120 to +121
with strict_role_checking():
if OrgStaffRole(org=org).has_user(user) or (course_key and user_has_role(user, CourseStaffRole(course_key))):
Comment on lines +538 to +542
with strict_role_checking():
staff_courses = UserBasedRole(request.user, CourseStaffRole.ROLE).courses_with_role()

# Courses for eSHE instructors
eshe_courses = UserBasedRole(request.user, eSHEInstructorRole.ROLE).courses_with_role()
get_courses_accessible_to_user
)
from common.djangoapps.course_action_state.models import CourseRerunState
from common.djangoapps.student.models.user import CourseAccessRole
number=course_location.course,
run=course_location.run
)
course = CourseOverviewFactory.create(id=course_location, org=course_location.org)
from django.test import TestCase, override_settings
from opaque_keys.edx.locator import CourseLocator

from common.djangoapps.student.models.user import CourseAccessRole
# eSHEInstructor-specific permissions
if course_key and user_has_role(user, eSHEInstructorRole(course_key)):
return STUDIO_VIEW_USERS | STUDIO_EDIT_CONTENT | STUDIO_VIEW_CONTENT

with self.assertNumQueries(2):
list(_accessible_courses_summary_iter(self.request))

def test_course_limited_staff_course_listing(self):
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants