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):
|
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:
|
Arguments:
|
||||||
course_key (CourseKey): Location of the course the user is trying to access.
|
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'):
|
if settings.FEATURES.get('EMBARGO'):
|
||||||
is_blocked = not check_course_access(course_key, **kwargs)
|
is_blocked = not check_course_access(course_key, **kwargs)
|
||||||
if is_blocked:
|
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):
|
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()
|
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
|
@classmethod
|
||||||
def _get_restricted_courses_from_cache(cls):
|
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)
|
restricted_courses = cache.get(cls.COURSE_LIST_CACHE_KEY)
|
||||||
if restricted_courses is None:
|
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)
|
cache.set(cls.COURSE_LIST_CACHE_KEY, restricted_courses)
|
||||||
return restricted_courses
|
return restricted_courses
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from embargo.models import Country, CountryAccessRule, RestrictedCourse
|
|||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@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.
|
"""Simulate that a course is restricted.
|
||||||
|
|
||||||
This does two things:
|
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, __ = RestrictedCourse.objects.get_or_create(course_key=course_key)
|
||||||
restricted_course.enroll_msg_key = 'default'
|
restricted_course.enroll_msg_key = 'default'
|
||||||
restricted_course.access_msg_key = 'default'
|
restricted_course.access_msg_key = 'default'
|
||||||
|
restricted_course.disable_access_check = disable_access_check
|
||||||
restricted_course.save()
|
restricted_course.save()
|
||||||
|
|
||||||
# Ensure that there is a blacklist rule for the country
|
# Ensure that there is a blacklist rule for the country
|
||||||
|
|||||||
@@ -51,10 +51,14 @@ class EmbargoMiddlewareAccessTests(UrlResetMixin, ModuleStoreTestCase):
|
|||||||
config_cache.clear()
|
config_cache.clear()
|
||||||
|
|
||||||
@patch.dict(settings.FEATURES, {'EMBARGO': True})
|
@patch.dict(settings.FEATURES, {'EMBARGO': True})
|
||||||
def test_blocked(self):
|
@ddt.data(True, False)
|
||||||
with restrict_course(self.course.id, access_point='courseware') as redirect_url:
|
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)
|
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})
|
@patch.dict(settings.FEATURES, {'EMBARGO': True})
|
||||||
def test_allowed(self):
|
def test_allowed(self):
|
||||||
|
|||||||
@@ -119,20 +119,28 @@ class RestrictedCourseTest(TestCase):
|
|||||||
# Warm the cache
|
# Warm the cache
|
||||||
with self.assertNumQueries(1):
|
with self.assertNumQueries(1):
|
||||||
RestrictedCourse.is_restricted_course(course_id)
|
RestrictedCourse.is_restricted_course(course_id)
|
||||||
|
RestrictedCourse.is_disabled_access_check(course_id)
|
||||||
|
|
||||||
# it should come from cache
|
# it should come from cache
|
||||||
with self.assertNumQueries(0):
|
with self.assertNumQueries(0):
|
||||||
RestrictedCourse.is_restricted_course(course_id)
|
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
|
# add new the course so the cache must get delete and again hit the db
|
||||||
new_course_id = CourseLocator('def', '123', 'doremi')
|
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):
|
with self.assertNumQueries(1):
|
||||||
RestrictedCourse.is_restricted_course(new_course_id)
|
RestrictedCourse.is_restricted_course(new_course_id)
|
||||||
|
RestrictedCourse.is_disabled_access_check(new_course_id)
|
||||||
|
|
||||||
# it should come from cache
|
# it should come from cache
|
||||||
with self.assertNumQueries(0):
|
with self.assertNumQueries(0):
|
||||||
RestrictedCourse.is_restricted_course(new_course_id)
|
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
|
# deleting an object will delete cache also.and hit db on
|
||||||
# get the is_restricted course
|
# get the is_restricted course
|
||||||
|
|||||||
Reference in New Issue
Block a user