107 lines
3.4 KiB
Python
107 lines
3.4 KiB
Python
"""
|
|
Simple utility functions for computing access.
|
|
It allows us to share code between access.py and block transformers.
|
|
"""
|
|
|
|
from __future__ import absolute_import
|
|
|
|
from datetime import datetime, timedelta
|
|
from logging import getLogger
|
|
|
|
from django.conf import settings
|
|
from django.utils.translation import ugettext as _
|
|
from pytz import UTC
|
|
|
|
from courseware.access_response import AccessResponse, StartDateError
|
|
from courseware.masquerade import get_course_masquerade, is_masquerading_as_student
|
|
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.roles import CourseBetaTesterRole
|
|
from xmodule.util.xmodule_django import get_current_request_hostname
|
|
|
|
DEBUG_ACCESS = False
|
|
log = getLogger(__name__)
|
|
|
|
ACCESS_GRANTED = AccessResponse(True)
|
|
ACCESS_DENIED = AccessResponse(False)
|
|
|
|
|
|
def debug(*args, **kwargs):
|
|
"""
|
|
Helper function for local debugging.
|
|
"""
|
|
# to avoid overly verbose output, this is off by default
|
|
if DEBUG_ACCESS:
|
|
log.debug(*args, **kwargs)
|
|
|
|
|
|
def adjust_start_date(user, days_early_for_beta, start, course_key):
|
|
"""
|
|
If user is in a beta test group, adjust the start date by the appropriate number of
|
|
days.
|
|
|
|
Returns:
|
|
A datetime. Either the same as start, or earlier for beta testers.
|
|
"""
|
|
if days_early_for_beta is None:
|
|
# bail early if no beta testing is set up
|
|
return start
|
|
|
|
if CourseBetaTesterRole(course_key).has_user(user):
|
|
debug(u"Adjust start time: user in beta role for %s", course_key)
|
|
delta = timedelta(days_early_for_beta)
|
|
effective = start - delta
|
|
return effective
|
|
|
|
return start
|
|
|
|
|
|
def check_start_date(user, days_early_for_beta, start, course_key, display_error_to_user=True):
|
|
"""
|
|
Verifies whether the given user is allowed access given the
|
|
start date and the Beta offset for the given course.
|
|
|
|
Arguments:
|
|
display_error_to_user: If True, display this error to users in the UI.
|
|
|
|
Returns:
|
|
AccessResponse: Either ACCESS_GRANTED or StartDateError.
|
|
"""
|
|
start_dates_disabled = settings.FEATURES['DISABLE_START_DATES']
|
|
masquerading_as_student = is_masquerading_as_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() 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
|
|
|
|
return StartDateError(start, display_error_to_user=display_error_to_user)
|
|
|
|
|
|
def in_preview_mode():
|
|
"""
|
|
Returns whether the user is in preview mode or not.
|
|
"""
|
|
hostname = get_current_request_hostname()
|
|
preview_lms_base = settings.FEATURES.get('PREVIEW_LMS_BASE', None)
|
|
return bool(preview_lms_base and hostname and hostname.split(':')[0] == preview_lms_base.split(':')[0])
|
|
|
|
|
|
def check_course_open_for_learner(user, course):
|
|
"""
|
|
Check if the course is open for learners based on the start date.
|
|
|
|
Returns:
|
|
AccessResponse: Either ACCESS_GRANTED or StartDateError.
|
|
"""
|
|
if COURSE_PRE_START_ACCESS_FLAG.is_enabled():
|
|
return ACCESS_GRANTED
|
|
return check_start_date(user, course.days_early_for_beta, course.start, course.id)
|