diff --git a/cms/envs/common.py b/cms/envs/common.py index 38913f537a..c79cfe7aa7 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -140,7 +140,6 @@ TEMPLATE_LOADERS = ( ) MIDDLEWARE_CLASSES = ( - 'contentserver.middleware.StaticContentServer', 'request_cache.middleware.RequestCache', 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.common.CommonMiddleware', @@ -150,6 +149,7 @@ MIDDLEWARE_CLASSES = ( # Instead of AuthenticationMiddleware, we use a cache-backed version 'cache_toolbox.middleware.CacheBackedAuthenticationMiddleware', + 'contentserver.middleware.StaticContentServer', 'django.contrib.messages.middleware.MessageMiddleware', 'track.middleware.TrackMiddleware', diff --git a/common/djangoapps/contentserver/middleware.py b/common/djangoapps/contentserver/middleware.py index 8d81929693..30ab977b96 100644 --- a/common/djangoapps/contentserver/middleware.py +++ b/common/djangoapps/contentserver/middleware.py @@ -46,10 +46,10 @@ class StaticContentServer(object): # Check that user has access to content if getattr(content, "locked", False): if not hasattr(request, "user") or not request.user.is_authenticated(): - return redirect('login') - course_id = "/".join([loc.org, loc.course, loc.name]) - if not CourseEnrollment.is_enrolled(request.user, course_id): - return redirect('dashboard') + return HttpResponse('Unauthorized', status=403) + course_partial_id = "/".join([loc.org, loc.course]) + if not CourseEnrollment.is_enrolled_by_partial(request.user, course_partial_id): + return HttpResponse('Unauthorized', status=403) # see if the last-modified at hasn't changed, if not return a 302 (Not Modified) diff --git a/common/djangoapps/contentserver/tests/test.py b/common/djangoapps/contentserver/tests/test.py index 340092b4d3..7313ba3f9b 100644 --- a/common/djangoapps/contentserver/tests/test.py +++ b/common/djangoapps/contentserver/tests/test.py @@ -94,8 +94,7 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase): # Case (1) resp = self.client.get(self.url) - self.assertEqual(resp.status_code, 302) - self.assertTrue(resp.has_header("LOCATION")) + self.assertEqual(resp.status_code, 403) # Case (2) # Create user and login @@ -110,13 +109,11 @@ class ContentStoreToyCourseTest(ModuleStoreTestCase): resp = self.client.get(self.url) log.debug("Received response %s", resp) - self.assertEqual(resp.status_code, 302) - self.assertTrue(resp.has_header("LOCATION")) - self.assertIn("dashboard", resp["LOCATION"]) + self.assertEqual(resp.status_code, 403) # Case (3) # Enroll student - course_id = "/".join([self.loc.org, self.loc.course, self.loc.name]) + course_id = "/".join([self.loc.org, self.loc.course, '2012_Fall']) CourseEnrollment.enroll(user, course_id) self.assertTrue(CourseEnrollment.is_enrolled(user, course_id)) diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py index 71cff4183b..8cda698d8b 100644 --- a/common/djangoapps/student/models.py +++ b/common/djangoapps/student/models.py @@ -843,6 +843,31 @@ class CourseEnrollment(models.Model): except cls.DoesNotExist: return False + @classmethod + def is_enrolled_by_partial(cls, user, course_id_partial): + """ + Returns `True` if the user is enrolled in a course that starts with + `course_id_partial`. Otherwise, returns False. + + Can be used to determine whether a student is enrolled in a course + whose run name is unknown. + + `user` is a Django User object. If it hasn't been saved yet (no `.id` + attribute), this method will automatically save it before + adding an enrollment for it. + + `course_id_partial` is a starting substring for a fully qualified + course_id (e.g. "edX/Test101/"). + """ + try: + return CourseEnrollment.objects.filter( + user=user, + course_id__startswith=course_id_partial, + is_active=1 + ).exists() + except cls.DoesNotExist: + return False + @classmethod def enrollment_mode_for_user(cls, user, course_id): """