diff --git a/lms/djangoapps/courseware/access_utils.py b/lms/djangoapps/courseware/access_utils.py index fa89e3228d..f071baad52 100644 --- a/lms/djangoapps/courseware/access_utils.py +++ b/lms/djangoapps/courseware/access_utils.py @@ -13,14 +13,11 @@ from pytz import UTC from courseware.access_response import AccessResponse, StartDateError from courseware.masquerade import ( get_course_masquerade, - is_masquerading_as_specific_student, is_masquerading_as_student ) -from crum import get_current_request from openedx.core.djangoapps.util.user_messages import PageLevelMessages from openedx.core.djangolib.markup import HTML from openedx.features.course_experience import COURSE_PRE_START_ACCESS_FLAG -from student.role_helpers import has_staff_roles from student.roles import CourseBetaTesterRole from xmodule.util.xmodule_django import get_current_request_hostname @@ -71,29 +68,18 @@ def check_start_date(user, days_early_for_beta, start, course_key): """ start_dates_disabled = settings.FEATURES['DISABLE_START_DATES'] masquerading_as_student = is_masquerading_as_student(user, course_key) - masquerading_as_specific_student = is_masquerading_as_specific_student(user, course_key) if start_dates_disabled and not masquerading_as_student: return ACCESS_GRANTED else: now = datetime.now(UTC) - if start is None or in_preview_mode(): + if start is None or in_preview_mode() or get_course_masquerade(user, course_key): return ACCESS_GRANTED effective_start = adjust_start_date(user, days_early_for_beta, start, course_key) if now > effective_start: return ACCESS_GRANTED - if get_course_masquerade(user, course_key): - if masquerading_as_student or (masquerading_as_specific_student and not has_staff_roles(user, course_key)): - request = get_current_request() - PageLevelMessages.register_warning_message( - request, - HTML(_('This user does not have access to this content due to the content start date')), - once_only=True - ) - return ACCESS_GRANTED - return StartDateError(start) diff --git a/lms/djangoapps/courseware/courses.py b/lms/djangoapps/courseware/courses.py index 4418961a16..caccff1313 100644 --- a/lms/djangoapps/courseware/courses.py +++ b/lms/djangoapps/courseware/courses.py @@ -8,6 +8,7 @@ from datetime import datetime import branding import pytz +from crum import get_current_request from openedx.features.course_duration_limits.access import AuditExpiredError from courseware.access import has_access from courseware.access_response import StartDateError, MilestoneAccessError @@ -19,6 +20,7 @@ from courseware.date_summary import ( VerifiedUpgradeDeadlineDate, CertificateAvailableDate ) +from courseware.masquerade import check_content_start_date_for_masquerade_user from courseware.model_data import FieldDataCache from courseware.module_render import get_module from django.conf import settings @@ -132,6 +134,9 @@ def check_course_access(course, user, action, check_if_enrolled=False, check_sur if has_access(user, 'staff', course.id): return + request = get_current_request() + check_content_start_date_for_masquerade_user(course.id, user, request, course.start) + access_response = has_access(user, action, course, course.id) if not access_response: # Redirect if StartDateError diff --git a/lms/djangoapps/courseware/masquerade.py b/lms/djangoapps/courseware/masquerade.py index d50ae4a92f..de8993b8c2 100644 --- a/lms/djangoapps/courseware/masquerade.py +++ b/lms/djangoapps/courseware/masquerade.py @@ -6,6 +6,7 @@ Which kind of view has been selected is stored in the session state. import logging +from datetime import datetime from django.conf import settings from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User @@ -13,10 +14,14 @@ from django.db.models import Q from django.utils.translation import ugettext as _ from django.views.decorators.http import require_POST from opaque_keys.edx.keys import CourseKey +from pytz import utc from web_fragments.fragment import Fragment from xblock.runtime import KeyValueStore +from openedx.core.djangoapps.util.user_messages import PageLevelMessages +from openedx.core.djangolib.markup import HTML from student.models import CourseEnrollment +from student.role_helpers import has_staff_roles from util.json_request import JsonResponse, expect_json from xmodule.partitions.partitions import NoSuchUserPartitionGroupError @@ -186,6 +191,30 @@ def get_masquerading_user_group(course_key, user, user_partition): return None +def check_content_start_date_for_masquerade_user(course_key, user, request, course_start, + chapter_start=None, section_start=None): + """ + Add a warning message if the masquerade user would not have access to this content + due to the content start date being in the future. + """ + now = datetime.now(utc) + most_future_date = course_start + if chapter_start and section_start: + most_future_date = max(course_start, chapter_start, section_start) + is_masquerading = get_course_masquerade(user, course_key) + if now < most_future_date and is_masquerading: + group_masquerade = is_masquerading_as_student(user, course_key) + specific_student_masquerade = is_masquerading_as_specific_student(user, course_key) + is_staff = has_staff_roles(user, course_key) + if group_masquerade or (specific_student_masquerade and not is_staff): + PageLevelMessages.register_warning_message( + request, + HTML(_('This user does not have access to this content because \ + the content start date is in the future')), + once_only=True + ) + + # Sentinel object to mark deleted objects in the session cache _DELETED_SENTINEL = object() diff --git a/lms/djangoapps/courseware/views/index.py b/lms/djangoapps/courseware/views/index.py index a961742b3e..a9768fc1af 100644 --- a/lms/djangoapps/courseware/views/index.py +++ b/lms/djangoapps/courseware/views/index.py @@ -55,7 +55,10 @@ from ..entrance_exams import ( user_can_skip_entrance_exam, user_has_passed_entrance_exam ) -from ..masquerade import setup_masquerade +from ..masquerade import ( + setup_masquerade, + check_content_start_date_for_masquerade_user +) from ..model_data import FieldDataCache from ..module_render import get_module_for_descriptor, toc_for_course @@ -182,6 +185,9 @@ class CoursewareIndex(View): self._save_positions() self._prefetch_and_bind_section() + check_content_start_date_for_masquerade_user(self.course_key, self.effective_user, request, + self.course.start, self.chapter.start, self.section.start) + if not request.user.is_authenticated: qs = urllib.urlencode({ 'course_id': self.course_key,