Enable un-authenticated handler urls

Updates to depend on the latest version of XBlock, which includes
support for service-to-service (thirdparty) handler urls, which aren't
authenticated with a user (unlike handler requests coming from the
xblock client-side javascript).

Co-author: Ned Batchelder <ned@edx.org>
This commit is contained in:
Calen Pennington
2013-11-26 14:09:50 -05:00
parent 329419696e
commit 6d613f9d4e
8 changed files with 65 additions and 21 deletions

View File

@@ -14,7 +14,7 @@ from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
from django.http import Http404
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from capa.xqueue_interface import XQueueInterface
from courseware.access import has_access
@@ -482,6 +482,14 @@ def xqueue_callback(request, course_id, userid, mod_id, dispatch):
return HttpResponse("")
@csrf_exempt
def handle_xblock_callback_noauth(request, course_id, usage_id, handler, suffix=None):
"""
Entry point for unauthenticated XBlock handlers.
"""
return _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, request.user)
def handle_xblock_callback(request, course_id, usage_id, handler, suffix=None):
"""
Generic view for extensions. This is where AJAX calls go.
@@ -496,6 +504,17 @@ def handle_xblock_callback(request, course_id, usage_id, handler, suffix=None):
the location and course_id do not identify a valid module, the module is
not accessible by the user, or the module raises NotFoundError. If the
module raises any other error, it will escape this function.
"""
if not request.user.is_authenticated():
raise PermissionDenied
return _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, request.user)
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, user):
"""
Invoke an XBlock handler, either authenticated or not.
"""
location = unquote_slashes(usage_id)
@@ -503,9 +522,6 @@ def handle_xblock_callback(request, course_id, usage_id, handler, suffix=None):
if not Location.is_valid(location):
raise Http404("Invalid location")
if not request.user.is_authenticated():
raise PermissionDenied
# Check submitted files
files = request.FILES or {}
error_msg = _check_files_limits(files)
@@ -525,15 +541,14 @@ def handle_xblock_callback(request, course_id, usage_id, handler, suffix=None):
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
course_id,
request.user,
user,
descriptor
)
instance = get_module(request.user, request, location, field_data_cache, course_id, grade_bucket_type='ajax')
instance = get_module(user, request, location, field_data_cache, course_id, grade_bucket_type='ajax')
if instance is None:
# Either permissions just changed, or someone is trying to be clever
# and load something they shouldn't have access to.
log.debug("No module %s for user %s -- access denied?", location, request.user)
log.debug("No module %s for user %s -- access denied?", location, user)
raise Http404
req = django_to_webob_request(request)

View File

@@ -185,9 +185,11 @@ class TestHandleXBlockCallback(ModuleStoreTestCase, LoginEnrollmentTestCase):
return mock_file
def test_invalid_location(self):
request = self.request_factory.post('dummy_url', data={'position': 1})
request.user = self.mock_user
with self.assertRaises(Http404):
render.handle_xblock_callback(
None,
request,
'dummy/course/id',
'invalid Location',
'dummy_handler'