feat!: remove all access to Old Mongo courses
Change has_access to deny 'load' support for Old Mongo courses. This is in service of dropping support for these ancient courses and removing legacy code that they rely on. DEPR-58
This commit is contained in:
@@ -27,6 +27,7 @@ from lms.djangoapps.courseware.access_response import (
|
|||||||
MilestoneAccessError,
|
MilestoneAccessError,
|
||||||
MobileAvailabilityError,
|
MobileAvailabilityError,
|
||||||
NoAllowedPartitionGroupsError,
|
NoAllowedPartitionGroupsError,
|
||||||
|
OldMongoAccessError,
|
||||||
VisibilityError
|
VisibilityError
|
||||||
)
|
)
|
||||||
from lms.djangoapps.courseware.access_utils import (
|
from lms.djangoapps.courseware.access_utils import (
|
||||||
@@ -329,6 +330,9 @@ def _has_access_course(user, action, courselike):
|
|||||||
# ).or(
|
# ).or(
|
||||||
# _has_staff_access_to_descriptor, user, courselike, courselike.id
|
# _has_staff_access_to_descriptor, user, courselike, courselike.id
|
||||||
# )
|
# )
|
||||||
|
if courselike.id.deprecated: # we no longer support accessing Old Mongo courses
|
||||||
|
return OldMongoAccessError(courselike)
|
||||||
|
|
||||||
visible_to_nonstaff = _visible_to_nonstaff_users(courselike)
|
visible_to_nonstaff = _visible_to_nonstaff_users(courselike)
|
||||||
if not visible_to_nonstaff:
|
if not visible_to_nonstaff:
|
||||||
staff_access = _has_staff_access_to_descriptor(user, courselike, courselike.id)
|
staff_access = _has_staff_access_to_descriptor(user, courselike, courselike.id)
|
||||||
|
|||||||
@@ -236,3 +236,16 @@ class AuthenticationRequiredAccessError(AccessError):
|
|||||||
developer_message = "User must be authenticated to view the course"
|
developer_message = "User must be authenticated to view the course"
|
||||||
user_message = _("You must be logged in to see this course")
|
user_message = _("You must be logged in to see this course")
|
||||||
super().__init__(error_code, developer_message, user_message)
|
super().__init__(error_code, developer_message, user_message)
|
||||||
|
|
||||||
|
|
||||||
|
class OldMongoAccessError(AccessError):
|
||||||
|
"""
|
||||||
|
Access denied because the course is in Old Mongo and we no longer support them. See DEPR-58.
|
||||||
|
"""
|
||||||
|
def __init__(self, courselike):
|
||||||
|
error_code = 'old_mongo'
|
||||||
|
developer_message = 'Access to Old Mongo courses is unsupported'
|
||||||
|
user_message = _('{course_name} is no longer available.').format(
|
||||||
|
course_name=courselike.display_name_with_default,
|
||||||
|
)
|
||||||
|
super().__init__(error_code, developer_message, user_message)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ from lms.djangoapps.courseware.access_response import (
|
|||||||
AuthenticationRequiredAccessError,
|
AuthenticationRequiredAccessError,
|
||||||
EnrollmentRequiredAccessError,
|
EnrollmentRequiredAccessError,
|
||||||
MilestoneAccessError,
|
MilestoneAccessError,
|
||||||
|
OldMongoAccessError,
|
||||||
StartDateError,
|
StartDateError,
|
||||||
)
|
)
|
||||||
from lms.djangoapps.courseware.date_summary import (
|
from lms.djangoapps.courseware.date_summary import (
|
||||||
@@ -213,6 +214,15 @@ def check_course_access_with_redirect(course, user, action, check_if_enrolled=Fa
|
|||||||
params=params.urlencode()
|
params=params.urlencode()
|
||||||
), access_response)
|
), access_response)
|
||||||
|
|
||||||
|
# Redirect if trying to access an Old Mongo course
|
||||||
|
if isinstance(access_response, OldMongoAccessError):
|
||||||
|
params = QueryDict(mutable=True)
|
||||||
|
params['access_response_error'] = access_response.user_message
|
||||||
|
raise CourseAccessRedirect('{dashboard_url}?{params}'.format(
|
||||||
|
dashboard_url=reverse('dashboard'),
|
||||||
|
params=params.urlencode(),
|
||||||
|
), access_response)
|
||||||
|
|
||||||
# Redirect if the user must answer a survey before entering the course.
|
# Redirect if the user must answer a survey before entering the course.
|
||||||
if isinstance(access_response, MilestoneAccessError):
|
if isinstance(access_response, MilestoneAccessError):
|
||||||
raise CourseAccessRedirect('{dashboard_url}'.format(
|
raise CourseAccessRedirect('{dashboard_url}'.format(
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ from lms.djangoapps.courseware.courses import (
|
|||||||
get_courses,
|
get_courses,
|
||||||
get_current_child
|
get_current_child
|
||||||
)
|
)
|
||||||
|
from lms.djangoapps.courseware.exceptions import CourseAccessRedirect
|
||||||
from lms.djangoapps.courseware.model_data import FieldDataCache
|
from lms.djangoapps.courseware.model_data import FieldDataCache
|
||||||
from lms.djangoapps.courseware.module_render import get_module_for_descriptor
|
from lms.djangoapps.courseware.module_render import get_module_for_descriptor
|
||||||
from lms.djangoapps.courseware.courseware_access_exception import CoursewareAccessException
|
from lms.djangoapps.courseware.courseware_access_exception import CoursewareAccessException
|
||||||
@@ -88,6 +89,18 @@ class CoursesTest(ModuleStoreTestCase):
|
|||||||
assert error.value.access_response.error_code == 'not_visible_to_user'
|
assert error.value.access_response.error_code == 'not_visible_to_user'
|
||||||
assert not error.value.access_response.has_access
|
assert not error.value.access_response.has_access
|
||||||
|
|
||||||
|
@ddt.data(GET_COURSE_WITH_ACCESS, GET_COURSE_OVERVIEW_WITH_ACCESS)
|
||||||
|
def test_old_mongo_access_error(self, course_access_func_name):
|
||||||
|
course_access_func = self.COURSE_ACCESS_FUNCS[course_access_func_name]
|
||||||
|
user = UserFactory.create()
|
||||||
|
with self.store.default_store(ModuleStoreEnum.Type.mongo):
|
||||||
|
course = CourseFactory.create()
|
||||||
|
|
||||||
|
with pytest.raises(CourseAccessRedirect) as error:
|
||||||
|
course_access_func(user, 'load', course.id)
|
||||||
|
assert error.value.access_error.error_code == 'old_mongo'
|
||||||
|
assert not error.value.access_error.has_access
|
||||||
|
|
||||||
@ddt.data(
|
@ddt.data(
|
||||||
(GET_COURSE_WITH_ACCESS, 2),
|
(GET_COURSE_WITH_ACCESS, 2),
|
||||||
(GET_COURSE_OVERVIEW_WITH_ACCESS, 0),
|
(GET_COURSE_OVERVIEW_WITH_ACCESS, 0),
|
||||||
|
|||||||
@@ -527,6 +527,25 @@ class TestCourseHomePageAccess(CourseHomePageTestCase):
|
|||||||
)
|
)
|
||||||
self.assertRedirects(response, expected_url)
|
self.assertRedirects(response, expected_url)
|
||||||
|
|
||||||
|
def test_old_mongo_access_error(self):
|
||||||
|
"""
|
||||||
|
Ensure that a user accessing an Old Mongo course sees a redirect to
|
||||||
|
the student dashboard, not a 404.
|
||||||
|
"""
|
||||||
|
course = CourseFactory.create(default_store=ModuleStoreEnum.Type.mongo)
|
||||||
|
user = UserFactory(password=self.TEST_PASSWORD)
|
||||||
|
self.client.login(username=user.username, password=self.TEST_PASSWORD)
|
||||||
|
|
||||||
|
response = self.client.get(course_home_url(course))
|
||||||
|
|
||||||
|
expected_params = QueryDict(mutable=True)
|
||||||
|
expected_params['access_response_error'] = f'{course.display_name_with_default} is no longer available.'
|
||||||
|
expected_url = '{url}?{params}'.format(
|
||||||
|
url=reverse('dashboard'),
|
||||||
|
params=expected_params.urlencode(),
|
||||||
|
)
|
||||||
|
self.assertRedirects(response, expected_url)
|
||||||
|
|
||||||
@mock.patch.dict(settings.FEATURES, {'DISABLE_START_DATES': False})
|
@mock.patch.dict(settings.FEATURES, {'DISABLE_START_DATES': False})
|
||||||
def test_expiration_banner_with_expired_upgrade_deadline(self):
|
def test_expiration_banner_with_expired_upgrade_deadline(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user