fix: added staff check for discussions iframe (#29617)
This commit is contained in:
@@ -1,32 +0,0 @@
|
||||
"""
|
||||
Permissions for program discussion api
|
||||
"""
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from rest_framework import permissions, status
|
||||
from rest_framework.exceptions import APIException
|
||||
|
||||
from lms.djangoapps.program_enrollments.api import get_program_enrollment
|
||||
|
||||
|
||||
class IsEnrolledInProgram(permissions.BasePermission):
|
||||
"""Permission that checks to see if the user is enrolled in the course or is staff."""
|
||||
def has_permission(self, request, view):
|
||||
|
||||
"""Returns true if the user is enrolled in program"""
|
||||
if not view.program:
|
||||
raise ProgramNotFound
|
||||
|
||||
try:
|
||||
get_program_enrollment(program_uuid=view.kwargs.get('program_uuid'), user=request.user)
|
||||
except ObjectDoesNotExist:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class ProgramNotFound(APIException):
|
||||
"""
|
||||
custom exception class for Program not found error
|
||||
"""
|
||||
status_code = status.HTTP_404_NOT_FOUND
|
||||
default_detail = 'Program not found for provided uuid'
|
||||
default_code = 'program_not_found'
|
||||
@@ -2,9 +2,10 @@
|
||||
Unit tests covering the program discussion iframe API.
|
||||
"""
|
||||
|
||||
import ddt
|
||||
from uuid import uuid4
|
||||
|
||||
from django.urls import reverse, reverse_lazy
|
||||
from django.urls import reverse_lazy
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag
|
||||
from lti_consumer.models import LtiConfiguration
|
||||
from markupsafe import Markup
|
||||
@@ -19,6 +20,7 @@ from openedx.core.djangoapps.catalog.tests.factories import CourseFactory, Cours
|
||||
from openedx.core.djangoapps.discussions.models import ProgramDiscussionsConfiguration
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@override_waffle_flag(ENABLE_PROGRAM_TAB_VIEW, active=True)
|
||||
@override_waffle_flag(ENABLE_MASTERS_PROGRAM_TAB_VIEW, active=True)
|
||||
class TestProgramDiscussionIframeView(SharedModuleStoreTestCase, ProgramCacheMixin):
|
||||
@@ -93,10 +95,15 @@ class TestProgramDiscussionIframeView(SharedModuleStoreTestCase, ProgramCacheMix
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.data, expected_data)
|
||||
|
||||
def test_api_returns_discussions_iframe(self):
|
||||
@ddt.data(True, False)
|
||||
def test_api_returns_discussions_iframe(self, staff):
|
||||
"""
|
||||
Test if API returns iframe in case ProgramDiscussionsConfiguration model contains proper data
|
||||
Test if API returns iframe in case ProgramDiscussionsConfiguration model contains proper data for staff
|
||||
and non staff. In case of non staff user must be be enrolled in program.
|
||||
"""
|
||||
if staff:
|
||||
self.user = UserFactory(is_staff=True)
|
||||
self.client.login(username=self.user.username, password=self.password)
|
||||
discussion_config = ProgramDiscussionsConfiguration.objects.create(
|
||||
program_uuid=self.program_uuid,
|
||||
enabled=True,
|
||||
@@ -114,18 +121,19 @@ class TestProgramDiscussionIframeView(SharedModuleStoreTestCase, ProgramCacheMix
|
||||
self.assertIsInstance(response.data['discussion']['iframe'], Markup)
|
||||
self.assertIn('iframe', str(response.data['discussion']['iframe']), )
|
||||
|
||||
def test_program_does_not_exist(self):
|
||||
def test_program_without_enrollment(self):
|
||||
"""
|
||||
Test if API returns 404 in case program does not exist
|
||||
"""
|
||||
response = self.client.get(reverse('program_discussion', kwargs={'program_uuid': str(uuid4())}))
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_program_access_denied(self):
|
||||
"""
|
||||
Test if API returns 403 in case user has no access to program
|
||||
Test if API returns default response in case a non staff user has no enrollment in the program
|
||||
"""
|
||||
self.user = UserFactory()
|
||||
self.client.login(username=self.user.username, password=self.password)
|
||||
response = self.client.get(self.url)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
default_response = {
|
||||
'tab_view_enabled': False,
|
||||
'discussion': {
|
||||
'configured': False,
|
||||
'iframe': ''
|
||||
}
|
||||
}
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.data, default_response)
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
"""Learner dashboard views"""
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.views.decorators.http import require_GET
|
||||
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
|
||||
from rest_framework import permissions, status
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from lms.djangoapps.learner_dashboard.utils import masters_program_tab_view_is_enabled
|
||||
from lms.djangoapps.program_enrollments.api import get_program_enrollment
|
||||
from common.djangoapps.edxmako.shortcuts import render_to_response
|
||||
from lms.djangoapps.learner_dashboard.permissions import IsEnrolledInProgram
|
||||
from common.djangoapps.student.roles import GlobalStaff
|
||||
from lms.djangoapps.learner_dashboard.programs import (
|
||||
ProgramDetailsFragmentView,
|
||||
ProgramDiscussionLTI,
|
||||
@@ -101,11 +104,32 @@ class ProgramDiscussionIframeView(APIView, ProgramSpecificViewMixin):
|
||||
}
|
||||
|
||||
"""
|
||||
authentication_classes = (BearerAuthentication, SessionAuthentication)
|
||||
permission_classes = (permissions.IsAuthenticated, IsEnrolledInProgram)
|
||||
authentication_classes = (JwtAuthentication, BearerAuthentication, SessionAuthentication)
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
def is_enrolled_or_staff(self, request, program_uuid):
|
||||
"""Returns true if the user is enrolled in the program or staff"""
|
||||
|
||||
if GlobalStaff().has_user(request.user):
|
||||
return True
|
||||
|
||||
try:
|
||||
get_program_enrollment(program_uuid=program_uuid, user=request.user)
|
||||
except ObjectDoesNotExist:
|
||||
return False
|
||||
return True
|
||||
|
||||
def get(self, request, program_uuid):
|
||||
""" GET handler """
|
||||
if not self.is_enrolled_or_staff(request, program_uuid):
|
||||
default_response = {
|
||||
'tab_view_enabled': False,
|
||||
'discussion': {
|
||||
'configured': False,
|
||||
'iframe': ''
|
||||
}
|
||||
}
|
||||
return Response(default_response, status=status.HTTP_200_OK)
|
||||
program_discussion_lti = ProgramDiscussionLTI(program_uuid, request)
|
||||
response_data = {
|
||||
'tab_view_enabled': masters_program_tab_view_is_enabled(),
|
||||
|
||||
Reference in New Issue
Block a user