AA-177: Add masquerading for course home MFE

- Looks at masquerading config for dates, outline, metadata, and
  celebration APIs in course_home_api / courseware_api.
- Consolidates and cleans up places we check whether masquerading
  gives us full access to a course.
This commit is contained in:
Michael Terry
2020-06-22 17:40:08 -04:00
parent cf5f9482e3
commit 3030efec78
40 changed files with 318 additions and 447 deletions

View File

@@ -4,7 +4,7 @@
from student.models import FBEEnrollmentExclusion
def is_in_holdback(user, enrollment):
def is_in_holdback(enrollment):
"""
Return true if given user is in holdback expermiment
"""

View File

@@ -11,6 +11,7 @@ from django.conf import settings
from lms.djangoapps.courseware.access_utils import ACCESS_DENIED, ACCESS_GRANTED
from lms.djangoapps.courseware.tabs import ExternalLinkCourseTab
from lms.djangoapps.courseware.tests.helpers import MasqueradeMixin
from student.models import CourseEnrollment, CourseEnrollmentCelebration
from student.tests.factories import CourseEnrollmentCelebrationFactory, UserFactory
from xmodule.modulestore.django import modulestore
@@ -159,7 +160,7 @@ class ResumeApiTestViews(BaseCoursewareTests, CompletionWaffleTestMixin):
@ddt.ddt
class CelebrationApiTestViews(BaseCoursewareTests):
class CelebrationApiTestViews(BaseCoursewareTests, MasqueradeMixin):
"""
Tests for the celebration API
"""
@@ -207,3 +208,20 @@ class CelebrationApiTestViews(BaseCoursewareTests):
response = self.client.post('/api/courseware/celebration/course-v1:does+not+exist',
{'first_section': True}, content_type='application/json')
assert response.status_code == 404
def test_masquerade(self):
self.user.is_staff = True
self.user.save()
user = UserFactory()
CourseEnrollment.enroll(user, self.course.id, 'verified')
response = self.client.post(self.url, {'first_section': True}, content_type='application/json')
assert response.status_code == 201
self.update_masquerade(username=user.username)
response = self.client.post(self.url, {'first_section': False}, content_type='application/json')
assert response.status_code == 202
celebration = CourseEnrollmentCelebration.objects.first()
assert celebration.celebrate_first_section # make sure it didn't change during masquerade attempt

View File

@@ -21,12 +21,6 @@ from edxnotes.helpers import is_feature_enabled
from lms.djangoapps.course_api.api import course_detail
from lms.djangoapps.courseware.access import has_access
from lms.djangoapps.courseware.courses import check_course_access
from lms.djangoapps.courseware.masquerade import is_masquerading
from lms.djangoapps.courseware.masquerade import is_masquerading_as_audit_enrollment
from lms.djangoapps.courseware.masquerade import is_masquerading_as_full_access
from lms.djangoapps.courseware.masquerade import is_masquerading_as_limited_access
from lms.djangoapps.courseware.masquerade import is_masquerading_as_non_audit_enrollment
from lms.djangoapps.courseware.masquerade import is_masquerading_as_staff
from lms.djangoapps.courseware.masquerade import setup_masquerade
from lms.djangoapps.courseware.module_render import get_module_by_usage_id
from lms.djangoapps.courseware.tabs import get_course_tab_list
@@ -96,27 +90,10 @@ class CoursewareMeta:
@property
def content_type_gating_enabled(self):
course_key = self.course_key
user = self.effective_user
is_enabled = None
course_masquerade = self.course_masquerade
if is_masquerading(user, course_key, course_masquerade):
if is_masquerading_as_staff(user, course_key):
is_enabled = False
elif is_masquerading_as_full_access(user, course_key, course_masquerade):
is_enabled = False
elif is_masquerading_as_non_audit_enrollment(user, course_key, course_masquerade):
is_enabled = False
elif is_masquerading_as_audit_enrollment(user, course_key, course_masquerade):
is_enabled = ContentTypeGatingConfig.enabled_for_course(course_key)
elif is_masquerading_as_limited_access(user, course_key, course_masquerade):
is_enabled = ContentTypeGatingConfig.enabled_for_course(course_key)
if is_enabled is None:
is_enabled = ContentTypeGatingConfig.enabled_for_enrollment(
user=user,
course_key=course_key,
)
return is_enabled
return ContentTypeGatingConfig.enabled_for_enrollment(
user=self.effective_user,
course_key=self.course_key,
)
@property
def can_show_upgrade_sock(self):
@@ -396,7 +373,7 @@ class Celebration(DeveloperErrorViewMixin, APIView):
**Returns**
* 200 or 201 on success with above fields.
* 200 or 201 or 202 on success with above fields.
* 400 if an invalid parameter was sent.
* 404 if the course is not available or cannot be seen.
"""
@@ -414,6 +391,16 @@ class Celebration(DeveloperErrorViewMixin, APIView):
"""
course_key = CourseKey.from_string(course_key_string)
# Check if we're masquerading as someone else. If so, we should just ignore this request.
_, user = setup_masquerade(
request,
course_key,
staff_access=has_access(request.user, 'staff', course_key),
reset_masquerade_data=True,
)
if user != request.user:
return Response(status=202) # "Accepted"
data = dict(request.data)
first_section = data.pop('first_section', None)
if data: