Commit 8407cac1 by Nimisha Asthagiri

Refactor has_access for re-usability.

parent d0795b27
...@@ -10,7 +10,7 @@ Note: The access control logic in this file does NOT check for enrollment in ...@@ -10,7 +10,7 @@ Note: The access control logic in this file does NOT check for enrollment in
If enrollment is to be checked, use get_course_with_access in courseware.courses. If enrollment is to be checked, use get_course_with_access in courseware.courses.
It is a wrapper around has_access that additionally checks for enrollment. It is a wrapper around has_access that additionally checks for enrollment.
""" """
from datetime import datetime, timedelta from datetime import datetime
import logging import logging
import pytz import pytz
...@@ -31,7 +31,6 @@ from xmodule.error_module import ErrorDescriptor ...@@ -31,7 +31,6 @@ from xmodule.error_module import ErrorDescriptor
from xmodule.x_module import XModule, DEPRECATION_VSCOMPAT_EVENT from xmodule.x_module import XModule, DEPRECATION_VSCOMPAT_EVENT
from xmodule.split_test_module import get_split_user_partitions from xmodule.split_test_module import get_split_user_partitions
from xmodule.partitions.partitions import NoSuchUserPartitionError, NoSuchUserPartitionGroupError from xmodule.partitions.partitions import NoSuchUserPartitionError, NoSuchUserPartitionGroupError
from xmodule.util.django import get_current_request_hostname
from external_auth.models import ExternalAuthMap from external_auth.models import ExternalAuthMap
from courseware.masquerade import get_masquerade_role, is_masquerading_as_student from courseware.masquerade import get_masquerade_role, is_masquerading_as_student
...@@ -56,26 +55,15 @@ from ccx_keys.locator import CCXLocator ...@@ -56,26 +55,15 @@ from ccx_keys.locator import CCXLocator
import dogstats_wrapper as dog_stats_api import dogstats_wrapper as dog_stats_api
from courseware.access_response import ( from courseware.access_response import (
AccessResponse,
MilestoneError, MilestoneError,
MobileAvailabilityError, MobileAvailabilityError,
StartDateError,
VisibilityError, VisibilityError,
) )
from courseware.access_utils import adjust_start_date, check_start_date, debug, ACCESS_GRANTED, ACCESS_DENIED
DEBUG_ACCESS = False
ACCESS_GRANTED = AccessResponse(True)
ACCESS_DENIED = AccessResponse(False)
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
def debug(*args, **kwargs):
# to avoid overly verbose output, this is off by default
if DEBUG_ACCESS:
log.debug(*args, **kwargs)
def has_access(user, action, obj, course_key=None): def has_access(user, action, obj, course_key=None):
""" """
Check whether a user has the access to do action on obj. Handles any magic Check whether a user has the access to do action on obj. Handles any magic
...@@ -172,24 +160,7 @@ def _can_access_descriptor_with_start_date(user, descriptor, course_key): # pyl ...@@ -172,24 +160,7 @@ def _can_access_descriptor_with_start_date(user, descriptor, course_key): # pyl
AccessResponse: The result of this access check. Possible results are AccessResponse: The result of this access check. Possible results are
ACCESS_GRANTED or a StartDateError. ACCESS_GRANTED or a StartDateError.
""" """
start_dates_disabled = settings.FEATURES['DISABLE_START_DATES'] return check_start_date(user, descriptor.days_early_for_beta, descriptor.start, course_key)
if start_dates_disabled and not is_masquerading_as_student(user, course_key):
return ACCESS_GRANTED
else:
now = datetime.now(UTC())
effective_start = _adjust_start_date_for_beta_testers(
user,
descriptor,
course_key=course_key
)
if (
descriptor.start is None
or now > effective_start
or in_preview_mode()
):
return ACCESS_GRANTED
return StartDateError(descriptor.start)
def _can_view_courseware_with_prerequisites(user, course): # pylint: disable=invalid-name def _can_view_courseware_with_prerequisites(user, course): # pylint: disable=invalid-name
...@@ -697,7 +668,7 @@ def _dispatch(table, action, user, obj): ...@@ -697,7 +668,7 @@ def _dispatch(table, action, user, obj):
type(obj), action)) type(obj), action))
def _adjust_start_date_for_beta_testers(user, descriptor, course_key=None): # pylint: disable=invalid-name def _adjust_start_date_for_beta_testers(user, descriptor, course_key): # pylint: disable=invalid-name
""" """
If user is in a beta test group, adjust the start date by the appropriate number of If user is in a beta test group, adjust the start date by the appropriate number of
days. days.
...@@ -716,21 +687,8 @@ def _adjust_start_date_for_beta_testers(user, descriptor, course_key=None): # p ...@@ -716,21 +687,8 @@ def _adjust_start_date_for_beta_testers(user, descriptor, course_key=None): # p
NOTE: For now, this function assumes that the descriptor's location is in the course NOTE: For now, this function assumes that the descriptor's location is in the course
the user is looking at. Once we have proper usages and definitions per the XBlock the user is looking at. Once we have proper usages and definitions per the XBlock
design, this should use the course the usage is in. design, this should use the course the usage is in.
NOTE: If testing manually, make sure FEATURES['DISABLE_START_DATES'] = False
in envs/dev.py!
""" """
if descriptor.days_early_for_beta is None: return adjust_start_date(descriptor.days_early_for_beta, descriptor.start, course_key)
# bail early if no beta testing is set up
return descriptor.start
if CourseBetaTesterRole(course_key).has_user(user):
debug("Adjust start time: user in beta role for %s", descriptor)
delta = timedelta(descriptor.days_early_for_beta)
effective = descriptor.start - delta
return effective
return descriptor.start
def _has_instructor_access_to_location(user, location, course_key=None): def _has_instructor_access_to_location(user, location, course_key=None):
...@@ -897,11 +855,3 @@ def get_user_role(user, course_key): ...@@ -897,11 +855,3 @@ def get_user_role(user, course_key):
return 'staff' return 'staff'
else: else:
return 'student' return 'student'
def in_preview_mode():
"""
Returns whether the user is in preview mode or not.
"""
hostname = get_current_request_hostname()
return bool(hostname and settings.PREVIEW_DOMAIN in hostname.split('.'))
"""
Simple utility functions for computing access.
It allows us to share code between access.py and block transformers.
"""
from datetime import timedelta
from django.conf import settings
from django.utils.timezone import now
from logging import getLogger
from student.roles import CourseBetaTesterRole
from courseware.masquerade import is_masquerading_as_student
from courseware.access_response import AccessResponse, StartDateError
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):
# 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):
"""
TODO
"""
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:
effective_start = adjust_start_date(user, days_early_for_beta, start, course_key)
if (
start is None
or now() > effective_start
or in_preview_mode()
):
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()
return bool(hostname and settings.PREVIEW_DOMAIN in hostname.split('.'))
...@@ -27,8 +27,9 @@ from django.db import transaction ...@@ -27,8 +27,9 @@ from django.db import transaction
from markupsafe import escape from markupsafe import escape
from courseware import grades from courseware import grades
from courseware.access import has_access, in_preview_mode, _adjust_start_date_for_beta_testers from courseware.access import has_access, _adjust_start_date_for_beta_testers
from courseware.access_response import StartDateError from courseware.access_response import StartDateError
from courseware.access_utils import in_preview_mode
from courseware.courses import ( from courseware.courses import (
get_courses, get_course, get_course_by_id, get_courses, get_course, get_course_by_id,
get_studio_url, get_course_with_access, get_studio_url, get_course_with_access,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment