feat: Update forum role membership api to DRF ( 11th ) (#35343)
* feat: upgrading simple api to drf compatible.
This commit is contained in:
@@ -81,7 +81,6 @@ from lms.djangoapps.course_home_api.toggles import course_home_mfe_progress_tab_
|
||||
from lms.djangoapps.courseware.access import has_access
|
||||
from lms.djangoapps.courseware.courses import get_course_with_access
|
||||
from lms.djangoapps.courseware.models import StudentModule
|
||||
from lms.djangoapps.discussion.django_comment_client.utils import has_forum_access
|
||||
from lms.djangoapps.instructor import enrollment
|
||||
from lms.djangoapps.instructor.access import ROLES, allow_access, list_with_level, revoke_access, update_forum_role
|
||||
from lms.djangoapps.instructor.constants import INVOICE_KEY
|
||||
@@ -115,17 +114,14 @@ from lms.djangoapps.instructor.views.serializer import (
|
||||
UserSerializer,
|
||||
UniqueStudentIdentifierSerializer,
|
||||
ProblemResetSerializer,
|
||||
RescoreEntranceExamSerializer,
|
||||
UpdateForumRoleMembershipSerializer,
|
||||
RescoreEntranceExamSerializer
|
||||
)
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from openedx.core.djangoapps.course_groups.cohorts import add_user_to_cohort, is_course_cohorted
|
||||
from openedx.core.djangoapps.course_groups.models import CourseUserGroup
|
||||
from openedx.core.djangoapps.django_comment_common.models import (
|
||||
CourseDiscussionSettings,
|
||||
FORUM_ROLE_ADMINISTRATOR,
|
||||
FORUM_ROLE_COMMUNITY_TA,
|
||||
FORUM_ROLE_GROUP_MODERATOR,
|
||||
FORUM_ROLE_MODERATOR,
|
||||
Role,
|
||||
)
|
||||
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
|
||||
@@ -3018,71 +3014,71 @@ class SendEmail(DeveloperErrorViewMixin, APIView):
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_course_permission(permissions.EDIT_FORUM_ROLES)
|
||||
@require_post_params(
|
||||
unique_student_identifier="email or username of user to change access",
|
||||
rolename="the forum role",
|
||||
action="'allow' or 'revoke'",
|
||||
)
|
||||
@common_exceptions_400
|
||||
def update_forum_role_membership(request, course_id):
|
||||
@method_decorator(cache_control(no_cache=True, no_store=True, must_revalidate=True), name='dispatch')
|
||||
class UpdateForumRoleMembership(APIView):
|
||||
"""
|
||||
Modify user's forum role.
|
||||
Modify a user's forum role in a course.
|
||||
|
||||
The requesting user must be at least staff.
|
||||
Staff forum admins can access all roles EXCEPT for FORUM_ROLE_ADMINISTRATOR
|
||||
which is limited to instructors.
|
||||
No one can revoke an instructors FORUM_ROLE_ADMINISTRATOR status.
|
||||
Permissions:
|
||||
- Must be authenticated.
|
||||
- Must be instructor or (staff + forum admin).
|
||||
- Only instructors can grant FORUM_ROLE_ADMINISTRATOR.
|
||||
|
||||
Query parameters:
|
||||
- `email` is the target users email
|
||||
- `rolename` is one of [FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_GROUP_MODERATOR,
|
||||
FORUM_ROLE_MODERATOR, FORUM_ROLE_COMMUNITY_TA]
|
||||
- `action` is one of ['allow', 'revoke']
|
||||
"""
|
||||
course_id = CourseKey.from_string(course_id)
|
||||
course = get_course_by_id(course_id)
|
||||
has_instructor_access = has_access(request.user, 'instructor', course)
|
||||
has_forum_admin = has_forum_access(
|
||||
request.user, course_id, FORUM_ROLE_ADMINISTRATOR
|
||||
)
|
||||
|
||||
unique_student_identifier = request.POST.get('unique_student_identifier')
|
||||
rolename = request.POST.get('rolename')
|
||||
action = request.POST.get('action')
|
||||
|
||||
# default roles require either (staff & forum admin) or (instructor)
|
||||
if not (has_forum_admin or has_instructor_access):
|
||||
return HttpResponseBadRequest(
|
||||
"Operation requires staff & forum admin or instructor access"
|
||||
)
|
||||
|
||||
# EXCEPT FORUM_ROLE_ADMINISTRATOR requires (instructor)
|
||||
if rolename == FORUM_ROLE_ADMINISTRATOR and not has_instructor_access:
|
||||
return HttpResponseBadRequest("Operation requires instructor access.")
|
||||
|
||||
if rolename not in [FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR, FORUM_ROLE_GROUP_MODERATOR,
|
||||
FORUM_ROLE_COMMUNITY_TA]:
|
||||
return HttpResponseBadRequest(strip_tags(
|
||||
f"Unrecognized rolename '{rolename}'."
|
||||
))
|
||||
|
||||
user = get_student_from_identifier(unique_student_identifier)
|
||||
if action == 'allow' and not is_user_enrolled_in_course(user, course_id):
|
||||
CourseEnrollment.enroll(user, course_id)
|
||||
try:
|
||||
update_forum_role(course_id, user, rolename, action)
|
||||
except Role.DoesNotExist:
|
||||
return HttpResponseBadRequest("Role does not exist.")
|
||||
|
||||
response_payload = {
|
||||
'course_id': str(course_id),
|
||||
'action': action,
|
||||
Request (POST body):
|
||||
{
|
||||
"unique_student_identifier": "user@example.com",
|
||||
"rolename": "FORUM_ROLE_MODERATOR",
|
||||
"action": "allow" or "revoke"
|
||||
}
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
"""
|
||||
permission_classes = (
|
||||
IsAuthenticated,
|
||||
permissions.InstructorPermission,
|
||||
permissions.ForumAdminRequiresInstructorAccess
|
||||
)
|
||||
permission_name = permissions.EDIT_FORUM_ROLES
|
||||
serializer_class = UpdateForumRoleMembershipSerializer
|
||||
|
||||
@method_decorator(ensure_csrf_cookie)
|
||||
def post(self, request, course_id):
|
||||
"""
|
||||
Handles role modification requests for a forum user.
|
||||
|
||||
Query parameters:
|
||||
- `email` is the target users email
|
||||
- `rolename` is one of [FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_GROUP_MODERATOR,
|
||||
FORUM_ROLE_MODERATOR, FORUM_ROLE_COMMUNITY_TA]
|
||||
- `action` is one of ['allow', 'revoke']
|
||||
"""
|
||||
course_id = CourseKey.from_string(course_id)
|
||||
serializer_data = UpdateForumRoleMembershipSerializer(data=request.data)
|
||||
|
||||
if not serializer_data.is_valid():
|
||||
return HttpResponseBadRequest(reason=serializer_data.errors)
|
||||
|
||||
user = serializer_data.validated_data.get('unique_student_identifier')
|
||||
if not user:
|
||||
return JsonResponse({'error': 'User does not exist.'}, status=400)
|
||||
|
||||
rolename = serializer_data.data['rolename']
|
||||
action = serializer_data.data['action']
|
||||
|
||||
if action == 'allow' and not is_user_enrolled_in_course(user, course_id):
|
||||
CourseEnrollment.enroll(user, course_id)
|
||||
|
||||
try:
|
||||
update_forum_role(course_id, user, rolename, action)
|
||||
except Role.DoesNotExist:
|
||||
return HttpResponseBadRequest("Role does not exist.")
|
||||
|
||||
return Response(
|
||||
{
|
||||
"course_id": str(course_id),
|
||||
"action": action,
|
||||
},
|
||||
status=status.HTTP_200_OK,
|
||||
)
|
||||
|
||||
|
||||
@require_POST
|
||||
|
||||
@@ -49,7 +49,7 @@ urlpatterns = [
|
||||
path('list_background_email_tasks', api.ListBackgroundEmailTasks.as_view(), name='list_background_email_tasks'),
|
||||
path('list_email_content', api.ListEmailContent.as_view(), name='list_email_content'),
|
||||
path('list_forum_members', api.ListForumMembers.as_view(), name='list_forum_members'),
|
||||
path('update_forum_role_membership', api.update_forum_role_membership, name='update_forum_role_membership'),
|
||||
path('update_forum_role_membership', api.UpdateForumRoleMembership.as_view(), name='update_forum_role_membership'),
|
||||
path('change_due_date', api.ChangeDueDate.as_view(), name='change_due_date'),
|
||||
path('send_email', api.SendEmail.as_view(), name='send_email'),
|
||||
path('reset_due_date', api.ResetDueDate.as_view(), name='reset_due_date'),
|
||||
|
||||
@@ -256,7 +256,27 @@ class StudentAttemptsSerializer(serializers.Serializer):
|
||||
if value is not None:
|
||||
return value in ['true', 'True', True]
|
||||
|
||||
return False
|
||||
|
||||
class UpdateForumRoleMembershipSerializer(AccessSerializer):
|
||||
"""
|
||||
Serializer for managing user's forum role.
|
||||
|
||||
This serializer extends the AccessSerializer to allow for different action
|
||||
choices specific to this API. It validates and processes the data required
|
||||
to modify user access within a system.
|
||||
|
||||
Attributes:
|
||||
unique_student_identifier (str): The email or username of the user whose access is being modified.
|
||||
rolename (str): The role name to assign to the user.
|
||||
action (str): The specific action to perform on the user's access, with options 'activate' or 'deactivate'.
|
||||
"""
|
||||
rolename = serializers.ChoiceField(
|
||||
choices=[
|
||||
FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR,
|
||||
FORUM_ROLE_GROUP_MODERATOR, FORUM_ROLE_COMMUNITY_TA
|
||||
],
|
||||
help_text="Rolename assign to given user."
|
||||
)
|
||||
|
||||
|
||||
class SendEmailSerializer(serializers.Serializer):
|
||||
|
||||
Reference in New Issue
Block a user