-
Notifications
You must be signed in to change notification settings - Fork 0
Crls/deny publish action for staff #69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: open-release/teak.nelp
Are you sure you want to change the base?
Crls/deny publish action for staff #69
Conversation
| ) | ||
| else: | ||
| log.info(f"Publish ALLOWED for user: {request.user.username}, roles={user_course_roles}, global_staff={is_global_staff}") | ||
| except Exception as e: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Broad exception
| log.info(f"request.json exists: {hasattr(request, 'json')}, request.json value: {getattr(request, 'json', None)}") | ||
|
|
||
| # Check if user is trying to publish and if they have permission | ||
| if request.method in ("POST", "PUT", "PATCH"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why GET not??
| user_course_roles = list(CourseAccessRole.objects.filter( | ||
| user=request.user, | ||
| course_id=usage_key.course_key, | ||
| role__in=['instructor', 'staff'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| role__in=['instructor', 'staff'] | |
| role__in=['instructor', 'staff'], |
| log.warning(f"Publish DENIED for staff-only user: {request.user.username} (global_staff={is_global_staff})") | ||
| return JsonResponse( | ||
| { | ||
| "error": _("Only instructors can publish content. Staff members do not have publish permissions.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you using _?
| # First, check for course-specific role | ||
| role_entry = CourseAccessRole.objects.filter( | ||
| user=user, | ||
| course_id=course_key |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| course_id=course_key | |
| course_id=course_key, |
| role_entry = CourseAccessRole.objects.filter( | ||
| user=user, | ||
| org=course_key.org, | ||
| course_id=CourseKeyField.Empty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| course_id=CourseKeyField.Empty | |
| course_id=CourseKeyField.Empty, |
| re_path( | ||
| fr'^course_user_role/{COURSE_ID_PATTERN}$', | ||
| CourseUserRoleView.as_view(), | ||
| name="course_user_role" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| name="course_user_role" | |
| name="course_user_role", |
| # Check if user is trying to publish and if they have permission | ||
| if request.method in ("POST", "PUT", "PATCH"): | ||
| try: | ||
| publish_action = request.json.get("publish") if hasattr(request, 'json') and request.json else None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| publish_action = request.json.get("publish") if hasattr(request, 'json') and request.json else None | |
| publish_action = request.json.get("publish") if hasattr(request, "json") and request.json else None |
single or double quotes
| from .course_index import CourseIndexSerializer | ||
| from .course_rerun import CourseRerunSerializer | ||
| from .course_team import CourseTeamSerializer | ||
| from .course_user_role import CourseUserRoleSerializer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CourseUserRoleSerializer Do you need it?
| from .course_rerun import CourseRerunView | ||
| from .course_waffle_flags import CourseWaffleFlagsView | ||
| from .course_team import CourseTeamView | ||
| from .course_user_role import CourseUserRoleView |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you use it? CourseUserRoleView
Description
This change enforces course-level role restrictions for content publishing in Studio, preventing users with only the "staff" role from publishing content, regardless of their GlobalStaff status.
Impact: Course Authors (Staff role specifically)
Previously, GlobalStaff users could bypass course-level permissions. Now, if a user is assigned the "staff" role (not "instructor") in a course, they cannot publish content even if they have GlobalStaff privileges. This ensures course-level role assignments take precedence over global permissions.
User Roles Affected:
Files Modified:
cms/djangoapps/contentstore/xblock_storage_handlers/view_handlers.py- Updatedhandle_xblock()permission logicSupporting information
Related to course permission management and role-based access control in Open edX Studio.
Testing instructions