ECOM-1421 implementing the functionality
This commit is contained in:
@@ -18,7 +18,8 @@ log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def redirect_if_blocked(course_key, access_point='enrollment', **kwargs):
|
||||
"""Redirect if the user does not have access to the course.
|
||||
"""Redirect if the user does not have access to the course. In case of blocked if access_point
|
||||
is not enrollment and course has enabled is_disabled_access_check then user can view that course.
|
||||
|
||||
Arguments:
|
||||
course_key (CourseKey): Location of the course the user is trying to access.
|
||||
@@ -30,7 +31,11 @@ def redirect_if_blocked(course_key, access_point='enrollment', **kwargs):
|
||||
if settings.FEATURES.get('EMBARGO'):
|
||||
is_blocked = not check_course_access(course_key, **kwargs)
|
||||
if is_blocked:
|
||||
return message_url_path(course_key, access_point)
|
||||
if access_point == "courseware":
|
||||
if not RestrictedCourse.is_disabled_access_check(course_key):
|
||||
return message_url_path(course_key, access_point)
|
||||
else:
|
||||
return message_url_path(course_key, access_point)
|
||||
|
||||
|
||||
def check_course_access(course_key, user=None, ip_address=None, url=None):
|
||||
|
||||
@@ -162,14 +162,39 @@ class RestrictedCourse(models.Model):
|
||||
"""
|
||||
return unicode(course_id) in cls._get_restricted_courses_from_cache()
|
||||
|
||||
@classmethod
|
||||
def is_disabled_access_check(cls, course_id):
|
||||
"""
|
||||
Check if the course is in restricted list has disabled_access_check
|
||||
|
||||
Args:
|
||||
course_id (str): course_id to look for
|
||||
|
||||
Returns:
|
||||
Boolean
|
||||
disabled_access_check attribute of restricted course
|
||||
"""
|
||||
|
||||
# checking is_restricted_course method also here to make sure course exists in the list otherwise in case of
|
||||
# no course found it will throw the key not found error on 'disable_access_check'
|
||||
return (
|
||||
cls.is_restricted_course(unicode(course_id))
|
||||
and cls._get_restricted_courses_from_cache().get(unicode(course_id))["disable_access_check"]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _get_restricted_courses_from_cache(cls):
|
||||
"""
|
||||
Cache all restricted courses and returns the list of course_keys that are restricted
|
||||
Cache all restricted courses and returns the dict of course_keys and disable_access_check that are restricted
|
||||
"""
|
||||
restricted_courses = cache.get(cls.COURSE_LIST_CACHE_KEY)
|
||||
if restricted_courses is None:
|
||||
restricted_courses = list(RestrictedCourse.objects.values_list('course_key', flat=True))
|
||||
restricted_courses = {
|
||||
unicode(course.course_key): {
|
||||
'disable_access_check': course.disable_access_check
|
||||
}
|
||||
for course in RestrictedCourse.objects.all()
|
||||
}
|
||||
cache.set(cls.COURSE_LIST_CACHE_KEY, restricted_courses)
|
||||
return restricted_courses
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ from embargo.models import Country, CountryAccessRule, RestrictedCourse
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def restrict_course(course_key, access_point="enrollment"):
|
||||
def restrict_course(course_key, access_point="enrollment", disable_access_check=False):
|
||||
"""Simulate that a course is restricted.
|
||||
|
||||
This does two things:
|
||||
@@ -58,6 +58,7 @@ def restrict_course(course_key, access_point="enrollment"):
|
||||
restricted_course, __ = RestrictedCourse.objects.get_or_create(course_key=course_key)
|
||||
restricted_course.enroll_msg_key = 'default'
|
||||
restricted_course.access_msg_key = 'default'
|
||||
restricted_course.disable_access_check = disable_access_check
|
||||
restricted_course.save()
|
||||
|
||||
# Ensure that there is a blacklist rule for the country
|
||||
|
||||
@@ -51,10 +51,14 @@ class EmbargoMiddlewareAccessTests(UrlResetMixin, ModuleStoreTestCase):
|
||||
config_cache.clear()
|
||||
|
||||
@patch.dict(settings.FEATURES, {'EMBARGO': True})
|
||||
def test_blocked(self):
|
||||
with restrict_course(self.course.id, access_point='courseware') as redirect_url:
|
||||
@ddt.data(True, False)
|
||||
def test_blocked(self, disable_access_check):
|
||||
with restrict_course(self.course.id, access_point='courseware', disable_access_check=disable_access_check) as redirect_url: # pylint: disable=line-too-long
|
||||
response = self.client.get(self.courseware_url)
|
||||
self.assertRedirects(response, redirect_url)
|
||||
if disable_access_check:
|
||||
self.assertEqual(response.status_code, 200)
|
||||
else:
|
||||
self.assertRedirects(response, redirect_url)
|
||||
|
||||
@patch.dict(settings.FEATURES, {'EMBARGO': True})
|
||||
def test_allowed(self):
|
||||
|
||||
@@ -119,20 +119,28 @@ class RestrictedCourseTest(TestCase):
|
||||
# Warm the cache
|
||||
with self.assertNumQueries(1):
|
||||
RestrictedCourse.is_restricted_course(course_id)
|
||||
RestrictedCourse.is_disabled_access_check(course_id)
|
||||
|
||||
# it should come from cache
|
||||
with self.assertNumQueries(0):
|
||||
RestrictedCourse.is_restricted_course(course_id)
|
||||
RestrictedCourse.is_disabled_access_check(course_id)
|
||||
|
||||
self.assertFalse(RestrictedCourse.is_disabled_access_check(course_id))
|
||||
|
||||
# add new the course so the cache must get delete and again hit the db
|
||||
new_course_id = CourseLocator('def', '123', 'doremi')
|
||||
RestrictedCourse.objects.create(course_key=new_course_id)
|
||||
RestrictedCourse.objects.create(course_key=new_course_id, disable_access_check=True)
|
||||
with self.assertNumQueries(1):
|
||||
RestrictedCourse.is_restricted_course(new_course_id)
|
||||
RestrictedCourse.is_disabled_access_check(new_course_id)
|
||||
|
||||
# it should come from cache
|
||||
with self.assertNumQueries(0):
|
||||
RestrictedCourse.is_restricted_course(new_course_id)
|
||||
RestrictedCourse.is_disabled_access_check(new_course_id)
|
||||
|
||||
self.assertTrue(RestrictedCourse.is_disabled_access_check(new_course_id))
|
||||
|
||||
# deleting an object will delete cache also.and hit db on
|
||||
# get the is_restricted course
|
||||
|
||||
Reference in New Issue
Block a user