fix: added staff check for discussions iframe (#29617)

This commit is contained in:
AsadAzam
2021-12-21 14:46:51 +05:00
committed by GitHub
parent c696469734
commit 7fba083a49
3 changed files with 48 additions and 48 deletions

View File

@@ -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'

View File

@@ -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)

View File

@@ -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(),