access_utils.py 2.84 KB
Newer Older
1 2 3 4 5 6
"""
Simple utility functions for computing access.
It allows us to share code between access.py and block transformers.
"""

from datetime import datetime, timedelta
7 8
from logging import getLogger

9 10
from django.conf import settings
from django.utils.timezone import UTC
11

12
from courseware.access_response import AccessResponse, StartDateError
13 14
from courseware.masquerade import is_masquerading_as_student
from student.roles import CourseBetaTesterRole
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
from xmodule.util.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("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):
    """
    Verifies whether the given user is allowed access given the
    start date and the Beta offset for the given course.

    Returns:
        AccessResponse: Either ACCESS_GRANTED or StartDateError.
    """
    start_dates_disabled = settings.FEATURES['DISABLE_START_DATES']
    if start_dates_disabled and not is_masquerading_as_student(user, course_key):
        return ACCESS_GRANTED
    else:
        now = datetime.now(UTC())
67 68 69
        if start is None or in_preview_mode():
            return ACCESS_GRANTED

70
        effective_start = adjust_start_date(user, days_early_for_beta, start, course_key)
71
        if now > effective_start:
72 73 74 75 76 77 78 79 80 81
            return ACCESS_GRANTED

        return StartDateError(start)


def in_preview_mode():
    """
    Returns whether the user is in preview mode or not.
    """
    hostname = get_current_request_hostname()
82 83
    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])
84 85 86 87 88 89 90 91 92


def is_course_open_for_learner(user, course):
    """
    Check if the course is open for learners based on the start date.
    """
    now = datetime.now(UTC())
    effective_start = adjust_start_date(user, course.days_early_for_beta, course.start, course.id)
    return not(not in_preview_mode() and now < effective_start)