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:
@@ -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)
|
||||
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user