From e3855cef54de7c468636273b9cb8159d2f9e1f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20M=C3=A9ndez?= Date: Wed, 1 Jul 2026 10:30:49 -0600 Subject: [PATCH] fix: Cannot rerun courses - authz role assignment expects rerun to already exist --- cms/djangoapps/contentstore/tasks.py | 5 ++++- cms/djangoapps/contentstore/views/course.py | 20 ++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/cms/djangoapps/contentstore/tasks.py b/cms/djangoapps/contentstore/tasks.py index a492b50c7c10..3d89d865237a 100644 --- a/cms/djangoapps/contentstore/tasks.py +++ b/cms/djangoapps/contentstore/tasks.py @@ -56,6 +56,7 @@ from cms.djangoapps.contentstore.toggles import enable_course_optimizer_check_prev_run_links from cms.djangoapps.contentstore.utils import ( IMPORTABLE_FILE_TYPES, + add_instructor, contains_course_reference, create_course_info_usage_key, create_or_update_xblock_upstream_link, @@ -188,7 +189,9 @@ def rerun_course(source_course_key_string, destination_course_key_string, user_i update_unit_discussion_state_from_discussion_blocks(destination_course_key, user_id) # set initial permissions for the user to access the course. - initialize_permissions(destination_course_key, User.objects.get(id=user_id)) + user = User.objects.get(id=user_id) + add_instructor(destination_course_key, user, user) + initialize_permissions(destination_course_key, user) # update state: Succeeded CourseRerunState.objects.succeeded(course_key=destination_course_key) diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index d3da7b9ec064..7c94271d8b27 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -419,8 +419,15 @@ def get_in_process_course_actions(request): exclude_args={'state': CourseRerunUIStateManager.State.SUCCEEDED}, should_display=True, ) - if user_has_course_permission( - request.user, COURSES_VIEW_COURSE.identifier, course.course_key, LegacyAuthoringPermission.READ + if ( + # The user who initiated the rerun can always see its status. + # This is needed because when the authz flag is enabled, permission + # checks require a CourseOverview which doesn't exist until the + # rerun task clones the course. + course.created_user == request.user + or user_has_course_permission( + request.user, COURSES_VIEW_COURSE.identifier, course.course_key, LegacyAuthoringPermission.READ + ) ) ] @@ -1324,8 +1331,13 @@ def rerun_course(user, source_course_key, org, number, run, fields, background=T raise PermissionDenied() # Make sure user has instructor and staff access to the destination course - # so the user can see the updated status for that course - add_instructor(destination_course_key, user, user) + # so the user can see the updated status for that course. + # When authz is enabled, we skip this because the authz layer requires a + # CourseOverview (which doesn't exist until the course is cloned in the task). + # In that case, visibility of the rerun status is granted by checking + # created_user on CourseRerunState instead. + if not core_toggles.enable_authz_course_authoring(destination_course_key): + add_instructor(destination_course_key, user, user) # Mark the action as initiated CourseRerunState.objects.initiated(source_course_key, destination_course_key, user, fields['display_name'])