Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion cms/djangoapps/contentstore/rest_api/v1/views/proctoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
from opaque_keys.edx.keys import CourseKey
from openedx_authz.constants.permissions import COURSES_MANAGE_PAGES_AND_RESOURCES
from rest_framework import status
from rest_framework.exceptions import NotFound
from rest_framework.exceptions import NotFound, PermissionDenied
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView
Expand All @@ -15,6 +16,8 @@
from cms.djangoapps.contentstore.views.course import get_course_and_check_access
from cms.djangoapps.models.settings.course_metadata import CourseMetadata
from common.djangoapps.student.auth import check_course_advanced_settings_access
from openedx.core.djangoapps.authz.constants import LegacyAuthoringPermission
from openedx.core.djangoapps.authz.decorators import user_has_course_permission
from openedx.core.djangoapps.course_apps.toggles import exams_ida_enabled
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin, verify_course_exists, view_auth_classes
from xmodule.course_block import ( # pylint: disable=wrong-import-order
Expand Down Expand Up @@ -200,6 +203,14 @@ def _get_and_validate_course_access(user, course_id):
f'Course with course_id {course_id} does not exist.'
)

if not user_has_course_permission(
user,
COURSES_MANAGE_PAGES_AND_RESOURCES.identifier,
course_key,
LegacyAuthoringPermission.WRITE,
):
raise PermissionDenied

return course_block


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from django.test.utils import override_settings
from django.urls import reverse
from edx_toggles.toggles.testutils import override_waffle_flag
from openedx_authz.constants.permissions import COURSES_VIEW_ADVANCED_SETTINGS
from openedx_authz.constants.permissions import COURSES_MANAGE_PAGES_AND_RESOURCES, COURSES_VIEW_ADVANCED_SETTINGS
from rest_framework import status
from rest_framework.test import APITestCase

Expand Down Expand Up @@ -42,6 +42,26 @@ def test_404_no_course_block(self):
"detail": f"Course with course_id {course_id} does not exist."
}

@patch.object(core_toggles.AUTHZ_COURSE_AUTHORING_FLAG, 'is_enabled', return_value=True)
@patch('openedx.core.djangoapps.authz.decorators.authz_api.is_user_allowed')
def test_authz_user_allowed(self, mock_is_user_allowed, mock_flag):
"""A user holding the authz manage_pages_and_resources permission can access."""
mock_is_user_allowed.return_value = True
self.client.login(username=self.global_staff.username, password=self.password)
response = self.make_request()
assert response.status_code == status.HTTP_200_OK
called_permission = mock_is_user_allowed.call_args[0][1]
assert called_permission == COURSES_MANAGE_PAGES_AND_RESOURCES.identifier

@patch.object(core_toggles.AUTHZ_COURSE_AUTHORING_FLAG, 'is_enabled', return_value=True)
@patch('openedx.core.djangoapps.authz.decorators.authz_api.is_user_allowed')
def test_authz_user_not_allowed(self, mock_is_user_allowed, mock_flag):
"""Without the authz manage_pages_and_resources permission, access is denied, even for staff."""
mock_is_user_allowed.return_value = False
self.client.login(username=self.global_staff.username, password=self.password)
response = self.make_request()
assert response.status_code == status.HTTP_403_FORBIDDEN


class ProctoringExamSettingsGetTests(
ProctoringExamSettingsTestcase, ModuleStoreTestCase, APITestCase
Expand Down
Loading