Add explicit masquerade support to courseware API
This commit is contained in:
@@ -20,12 +20,17 @@ from pytz import utc
|
|||||||
from web_fragments.fragment import Fragment
|
from web_fragments.fragment import Fragment
|
||||||
from xblock.runtime import KeyValueStore
|
from xblock.runtime import KeyValueStore
|
||||||
|
|
||||||
|
from course_modes.models import CourseMode
|
||||||
from openedx.core.djangoapps.util.user_messages import PageLevelMessages
|
from openedx.core.djangoapps.util.user_messages import PageLevelMessages
|
||||||
from openedx.core.djangolib.markup import HTML
|
from openedx.core.djangolib.markup import HTML
|
||||||
|
from openedx.features.content_type_gating.helpers import CONTENT_GATING_PARTITION_ID
|
||||||
|
from openedx.features.content_type_gating.helpers import FULL_ACCESS
|
||||||
|
from openedx.features.content_type_gating.helpers import LIMITED_ACCESS
|
||||||
from student.models import CourseEnrollment
|
from student.models import CourseEnrollment
|
||||||
from student.role_helpers import has_staff_roles
|
from student.role_helpers import has_staff_roles
|
||||||
from util.json_request import JsonResponse, expect_json
|
from util.json_request import JsonResponse, expect_json
|
||||||
from xmodule.modulestore.django import modulestore
|
from xmodule.modulestore.django import modulestore
|
||||||
|
from xmodule.partitions.partitions import ENROLLMENT_TRACK_PARTITION_ID
|
||||||
from xmodule.partitions.partitions import NoSuchUserPartitionGroupError
|
from xmodule.partitions.partitions import NoSuchUserPartitionGroupError
|
||||||
from xmodule.partitions.partitions_service import get_all_partitions_for_course
|
from xmodule.partitions.partitions_service import get_all_partitions_for_course
|
||||||
|
|
||||||
@@ -229,6 +234,83 @@ def get_masquerade_role(user, course_key):
|
|||||||
return course_masquerade.role if course_masquerade else None
|
return course_masquerade.role if course_masquerade else None
|
||||||
|
|
||||||
|
|
||||||
|
def _get_masquerade_group_id(target_user_partition_id, user, course_key, course_masquerade=None):
|
||||||
|
"""
|
||||||
|
Return the masqueraded track's group ID
|
||||||
|
if it's in the specified user partition,
|
||||||
|
otherwise, return None
|
||||||
|
"""
|
||||||
|
course_masquerade = course_masquerade or get_course_masquerade(user, course_key)
|
||||||
|
if course_masquerade is not None:
|
||||||
|
user_partition_id = course_masquerade.user_partition_id
|
||||||
|
if user_partition_id == target_user_partition_id:
|
||||||
|
group_id = course_masquerade.group_id
|
||||||
|
if group_id:
|
||||||
|
return group_id
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def is_masquerading(user, course_key, course_masquerade=None):
|
||||||
|
"""
|
||||||
|
Return if the user is masquerading at all
|
||||||
|
"""
|
||||||
|
course_masquerade = course_masquerade or get_course_masquerade(user, course_key)
|
||||||
|
_is_masquerading = course_masquerade is not None
|
||||||
|
return _is_masquerading
|
||||||
|
|
||||||
|
|
||||||
|
def is_masquerading_as_non_audit_enrollment(user, course_key, course_masquerade=None):
|
||||||
|
"""
|
||||||
|
Return if the user is a staff member masquerading as a user
|
||||||
|
in _any_ enrollment track _except_ audit
|
||||||
|
"""
|
||||||
|
group_id = _get_masquerade_group_id(ENROLLMENT_TRACK_PARTITION_ID, user, course_key, course_masquerade)
|
||||||
|
audit_mode_id = settings.COURSE_ENROLLMENT_MODES.get(CourseMode.AUDIT, {}).get('id')
|
||||||
|
if group_id is not None:
|
||||||
|
if group_id != audit_mode_id:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def is_masquerading_as_audit_enrollment(user, course_key, course_masquerade=None):
|
||||||
|
"""
|
||||||
|
Return if the user is a staff member masquerading as a user
|
||||||
|
in the audit enrollment track
|
||||||
|
"""
|
||||||
|
group_id = _get_masquerade_group_id(ENROLLMENT_TRACK_PARTITION_ID, user, course_key, course_masquerade)
|
||||||
|
audit_mode_id = settings.COURSE_ENROLLMENT_MODES.get(CourseMode.AUDIT, {}).get('id')
|
||||||
|
_is_masquerading = group_id == audit_mode_id
|
||||||
|
return _is_masquerading
|
||||||
|
|
||||||
|
|
||||||
|
def is_masquerading_as_full_access(user, course_key, course_masquerade=None):
|
||||||
|
"""
|
||||||
|
Return if the user is a staff member masquerading as a user
|
||||||
|
in the Full-Access track
|
||||||
|
"""
|
||||||
|
group_id = _get_masquerade_group_id(CONTENT_GATING_PARTITION_ID, user, course_key, course_masquerade)
|
||||||
|
_is_masquerading = group_id == FULL_ACCESS.id
|
||||||
|
return _is_masquerading
|
||||||
|
|
||||||
|
|
||||||
|
def is_masquerading_as_limited_access(user, course_key, course_masquerade=None):
|
||||||
|
"""
|
||||||
|
Return if the user is a staff member masquerading as a user
|
||||||
|
in the Limited-Access track
|
||||||
|
"""
|
||||||
|
group_id = _get_masquerade_group_id(CONTENT_GATING_PARTITION_ID, user, course_key, course_masquerade)
|
||||||
|
_is_masquerading = group_id == LIMITED_ACCESS.id
|
||||||
|
return _is_masquerading
|
||||||
|
|
||||||
|
|
||||||
|
def is_masquerading_as_staff(user, course_key):
|
||||||
|
"""
|
||||||
|
Return if the user is a staff member masquerading as user
|
||||||
|
that is itself a staff user
|
||||||
|
"""
|
||||||
|
return get_masquerade_role(user, course_key) == 'staff'
|
||||||
|
|
||||||
|
|
||||||
def is_masquerading_as_student(user, course_key):
|
def is_masquerading_as_student(user, course_key):
|
||||||
"""
|
"""
|
||||||
Returns true if the user is a staff member masquerading as a student.
|
Returns true if the user is a staff member masquerading as a student.
|
||||||
@@ -270,8 +352,8 @@ def check_content_start_date_for_masquerade_user(course_key, user, request, cour
|
|||||||
most_future_date = course_start
|
most_future_date = course_start
|
||||||
if chapter_start and section_start:
|
if chapter_start and section_start:
|
||||||
most_future_date = max(course_start, chapter_start, section_start)
|
most_future_date = max(course_start, chapter_start, section_start)
|
||||||
is_masquerading = get_course_masquerade(user, course_key)
|
_is_masquerading = get_course_masquerade(user, course_key)
|
||||||
if now < most_future_date and is_masquerading:
|
if now < most_future_date and _is_masquerading:
|
||||||
group_masquerade = is_masquerading_as_student(user, course_key)
|
group_masquerade = is_masquerading_as_student(user, course_key)
|
||||||
specific_student_masquerade = is_masquerading_as_specific_student(user, course_key)
|
specific_student_masquerade = is_masquerading_as_specific_student(user, course_key)
|
||||||
is_staff = has_staff_roles(user, course_key)
|
is_staff = has_staff_roles(user, course_key)
|
||||||
|
|||||||
@@ -21,6 +21,13 @@ from edxnotes.helpers import is_feature_enabled
|
|||||||
from lms.djangoapps.course_api.api import course_detail
|
from lms.djangoapps.course_api.api import course_detail
|
||||||
from lms.djangoapps.courseware.access import has_access
|
from lms.djangoapps.courseware.access import has_access
|
||||||
from lms.djangoapps.courseware.courses import check_course_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.module_render import get_module_by_usage_id
|
||||||
from lms.djangoapps.courseware.tabs import get_course_tab_list
|
from lms.djangoapps.courseware.tabs import get_course_tab_list
|
||||||
from lms.djangoapps.courseware.utils import can_show_verified_upgrade
|
from lms.djangoapps.courseware.utils import can_show_verified_upgrade
|
||||||
@@ -47,17 +54,21 @@ class CoursewareMeta:
|
|||||||
course_key,
|
course_key,
|
||||||
)
|
)
|
||||||
self.effective_user = self.overview.effective_user
|
self.effective_user = self.overview.effective_user
|
||||||
|
# We need to memoize `is_staff` _before_ we configure masquerade.
|
||||||
|
self.is_staff = has_access(self.effective_user, 'staff', self.overview).has_access
|
||||||
self.course_key = course_key
|
self.course_key = course_key
|
||||||
self.enrollment_object = CourseEnrollment.get_enrollment(self.effective_user, self.course_key,
|
self.enrollment_object = CourseEnrollment.get_enrollment(self.effective_user, self.course_key,
|
||||||
select_related=['celebration'])
|
select_related=['celebration'])
|
||||||
|
course_masquerade, _user = setup_masquerade(
|
||||||
|
request,
|
||||||
|
course_key,
|
||||||
|
staff_access=self.is_staff,
|
||||||
|
)
|
||||||
|
self.course_masquerade = course_masquerade
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
return getattr(self.overview, name)
|
return getattr(self.overview, name)
|
||||||
|
|
||||||
@property
|
|
||||||
def is_staff(self):
|
|
||||||
return has_access(self.effective_user, 'staff', self.overview).has_access
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def enrollment(self):
|
def enrollment(self):
|
||||||
"""
|
"""
|
||||||
@@ -85,10 +96,27 @@ class CoursewareMeta:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def content_type_gating_enabled(self):
|
def content_type_gating_enabled(self):
|
||||||
return ContentTypeGatingConfig.enabled_for_enrollment(
|
course_key = self.course_key
|
||||||
user=self.effective_user,
|
user = self.effective_user
|
||||||
course_key=self.course_key,
|
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
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def can_show_upgrade_sock(self):
|
def can_show_upgrade_sock(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user