Beispiel #1
0
def aside_handler(request,
                  aside_id,
                  handler_slug,
                  suffix='',
                  authenticated=True):
    """The view function for authenticated handler requests."""
    if authenticated:
        student_id = get_student_id(request)
        log.info(u"Start handler %s/%s for student %s", aside_id, handler_slug,
                 student_id)
    else:
        student_id = "none"
        log.info(u"Start handler %s/%s", aside_id, handler_slug)

    runtime = WorkbenchRuntime(student_id)

    try:
        block = runtime.get_aside(aside_id)
    except NoSuchUsage:
        raise Http404

    request = django_to_webob_request(request)
    request.path_info_pop()
    request.path_info_pop()
    result = block.runtime.handle(block, handler_slug, request, suffix)
    log.info(u"End handler %s/%s", aside_id, handler_slug)
    return webob_to_django_response(result)
Beispiel #2
0
def component_handler(request, usage_id, handler, suffix=""):
    """
    Dispatch an AJAX action to an xblock

    Args:
        usage_id: The usage-id of the block to dispatch to, passed through `quote_slashes`
        handler (str): The handler to execute
        suffix (str): The remainder of the url to be passed to the handler

    Returns:
        :class:`django.http.HttpResponse`: The response from the handler, converted to a
            django response
    """

    location = unquote_slashes(usage_id)

    descriptor = modulestore().get_item(location)
    # Let the module handle the AJAX
    req = django_to_webob_request(request)

    try:
        resp = descriptor.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.info("XBlock %s attempted to access missing handler %r", descriptor, handler, exc_info=True)
        raise Http404

    modulestore().save_xmodule(descriptor)

    return webob_to_django_response(resp)
Beispiel #3
0
def component_handler(request, usage_key_string, handler, suffix=''):
    """
    Dispatch an AJAX action to an xblock

    Args:
        usage_id: The usage-id of the block to dispatch to
        handler (str): The handler to execute
        suffix (str): The remainder of the url to be passed to the handler

    Returns:
        :class:`django.http.HttpResponse`: The response from the handler, converted to a
            django response
    """

    usage_key = UsageKey.from_string(usage_key_string)

    descriptor = get_modulestore(usage_key).get_item(usage_key)
    # Let the module handle the AJAX
    req = django_to_webob_request(request)

    try:
        resp = descriptor.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.info("XBlock %s attempted to access missing handler %r", descriptor, handler, exc_info=True)
        raise Http404

    # unintentional update to handle any side effects of handle call; so, request user didn't author
    # the change
    get_modulestore(usage_key).update_item(descriptor, None)

    return webob_to_django_response(resp)
Beispiel #4
0
def preview_handler(request, usage_key_string, handler, suffix=''):
    """
    Dispatch an AJAX action to an xblock

    usage_key_string: The usage_key_string-id of the block to dispatch to, passed through `quote_slashes`
    handler: The handler to execute
    suffix: The remainder of the url to be passed to the handler
    """
    usage_key = UsageKey.from_string(usage_key_string)

    descriptor = modulestore().get_item(usage_key)
    instance = _load_preview_module(request, descriptor)
    # Let the module handle the AJAX
    req = django_to_webob_request(request)
    try:
        resp = instance.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.exception("XBlock %s attempted to access missing handler %r", instance, handler)
        raise Http404

    except NotFoundError:
        log.exception("Module indicating to user that request doesn't exist")
        raise Http404

    except ProcessingError:
        log.warning("Module raised an error while processing AJAX request",
                    exc_info=True)
        return HttpResponseBadRequest()

    except Exception:
        log.exception("error processing ajax call")
        raise

    return webob_to_django_response(resp)
Beispiel #5
0
def component_handler(request, usage_key_string, handler, suffix=''):
    """
    Dispatch an AJAX action to an xblock

    Args:
        usage_id: The usage-id of the block to dispatch to
        handler (str): The handler to execute
        suffix (str): The remainder of the url to be passed to the handler

    Returns:
        :class:`django.http.HttpResponse`: The response from the handler, converted to a
            django response
    """

    usage_key = UsageKey.from_string(usage_key_string)

    descriptor = modulestore().get_item(usage_key)
    # Let the module handle the AJAX
    req = django_to_webob_request(request)

    try:
        resp = descriptor.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.info("XBlock %s attempted to access missing handler %r",
                 descriptor,
                 handler,
                 exc_info=True)
        raise Http404

    # unintentional update to handle any side effects of handle call
    # could potentially be updating actual course data or simply caching its values
    modulestore().update_item(descriptor, request.user.id)

    return webob_to_django_response(resp)
Beispiel #6
0
def component_handler(request, usage_key_string, handler, suffix=''):
    """
    Dispatch an AJAX action to an xblock

    Args:
        usage_id: The usage-id of the block to dispatch to
        handler (str): The handler to execute
        suffix (str): The remainder of the url to be passed to the handler

    Returns:
        :class:`django.http.HttpResponse`: The response from the handler, converted to a
            django response
    """

    usage_key = UsageKey.from_string(usage_key_string)

    descriptor = modulestore().get_item(usage_key)
    descriptor.xmodule_runtime = StudioEditModuleRuntime(request.user)
    # Let the module handle the AJAX
    req = django_to_webob_request(request)

    try:
        resp = descriptor.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.info("XBlock %s attempted to access missing handler %r", descriptor, handler, exc_info=True)
        raise Http404

    # unintentional update to handle any side effects of handle call
    # could potentially be updating actual course data or simply caching its values
    modulestore().update_item(descriptor, request.user.id)

    return webob_to_django_response(resp)
Beispiel #7
0
def preview_handler(request, usage_key_string, handler, suffix=''):
    """
    Dispatch an AJAX action to an xblock

    usage_key_string: The usage_key_string-id of the block to dispatch to, passed through `quote_slashes`
    handler: The handler to execute
    suffix: The remainder of the url to be passed to the handler
    """
    usage_key = UsageKey.from_string(usage_key_string)

    descriptor = modulestore().get_item(usage_key)
    instance = _load_preview_module(request, descriptor)
    # Let the module handle the AJAX
    req = django_to_webob_request(request)
    try:
        resp = instance.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.exception("XBlock %s attempted to access missing handler %r", instance, handler)
        raise Http404

    except NotFoundError:
        log.exception("Module indicating to user that request doesn't exist")
        raise Http404

    except ProcessingError:
        log.warning("Module raised an error while processing AJAX request",
                    exc_info=True)
        return HttpResponseBadRequest()

    except Exception:
        log.exception("error processing ajax call")
        raise

    return webob_to_django_response(resp)
Beispiel #8
0
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)

    # Check parameters and fail fast if there's a problem
    if not Location.is_valid(location):
        raise Http404("Invalid location")

    # Check submitted files
    files = request.FILES or {}
    error_msg = _check_files_limits(files)
    if error_msg:
        return HttpResponse(json.dumps({"success": error_msg}))

    try:
        descriptor = modulestore().get_instance(course_id, location)
    except ItemNotFoundError:
        log.warn(
            "Invalid location for course id {course_id}: {location}".format(course_id=course_id, location=location)
        )
        raise Http404

    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course_id, user, descriptor)
    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, user)
        raise Http404

    req = django_to_webob_request(request)
    try:
        resp = instance.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.exception("XBlock %s attempted to access missing handler %r", instance, handler)
        raise Http404

    # If we can't find the module, respond with a 404
    except NotFoundError:
        log.exception("Module indicating to user that request doesn't exist")
        raise Http404

    # For XModule-specific errors, we log the error and respond with an error message
    except ProcessingError as err:
        log.warning("Module encountered an error while processing AJAX call", exc_info=True)
        return JsonResponse(object={"success": err.args[0]}, status=200)

    # If any other error occurred, re-raise it to trigger a 500 response
    except Exception:
        log.exception("error executing xblock handler")
        raise

    return webob_to_django_response(resp)
Beispiel #9
0
def xblock_handler(request, user_id, secure_token, usage_key_str, handler_name,
                   suffix):
    """
    Run an XBlock's handler and return the result

    This endpoint has a unique authentication scheme that involves a temporary
    auth token included in the URL (see below). As a result it can be exempt
    from CSRF, session auth, and JWT/OAuth.
    """
    try:
        usage_key = UsageKey.from_string(usage_key_str)
    except InvalidKeyError as e:
        raise Http404 from e

    # To support sandboxed XBlocks, custom frontends, and other use cases, we
    # authenticate requests using a secure token in the URL. see
    # openedx.core.djangoapps.xblock.utils.get_secure_hash_for_xblock_handler
    # for details and rationale.
    if not validate_secure_token_for_xblock_handler(user_id, usage_key_str,
                                                    secure_token):
        raise PermissionDenied("Invalid/expired auth token.")
    if request.user.is_authenticated:
        # The user authenticated twice, e.g. with session auth and the token.
        # This can happen if not running the XBlock in a sandboxed iframe.
        # Just make sure the session auth matches the token:
        if request.user.id != int(user_id):
            raise AuthenticationFailed("Authentication conflict.")
        user = request.user
    elif user_id.isdigit():
        # This is a normal (integer) user ID for a registered user.
        # This is the "normal" way this view gets used, with a sandboxed iframe.
        user = User.objects.get(pk=int(user_id))
    elif user_id.startswith("anon"):
        # This is a non-registered (anonymous) user:
        assert request.user.is_anonymous
        assert not hasattr(request.user, 'xblock_id_for_anonymous_user')
        user = request.user  # An AnonymousUser
        # Since this particular view usually gets called from a sandboxed iframe
        # we won't have access to the LMS session data for this user (the iframe
        # has a new, empty session). So we need to save the identifier for this
        # anonymous user (from the URL) on the user object, so that the runtime
        # can get it (instead of generating a new one and saving it into this
        # new empty session)
        # See djangoapps.xblock.utils.get_xblock_id_for_anonymous_user()
        user.xblock_id_for_anonymous_user = user_id
    else:
        raise AuthenticationFailed("Invalid user ID format.")

    request_webob = DjangoWebobRequest(
        request
    )  # Convert from django request to the webob format that XBlocks expect
    block = load_block(usage_key, user)
    # Run the handler, and save any resulting XBlock field value changes:
    response_webob = block.handle(handler_name, request_webob, suffix)
    response = webob_to_django_response(response_webob)
    return response
Beispiel #10
0
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix):
    """
    Invoke an XBlock handler, either authenticated or not.

    Arguments:
        request (HttpRequest): the current request
        course_id (str): A string of the form org/course/run
        usage_id (str): A string of the form i4x://org/course/category/name@revision
        handler (str): The name of the handler to invoke
        suffix (str): The suffix to pass to the handler when invoked
    """

    # Check submitted files
    files = request.FILES or {}
    error_msg = _check_files_limits(files)
    if error_msg:
        return JsonResponse(object={
            'success': False,
            'msg': error_msg
        },
                            status=413)

    instance, tracking_context = _get_module_by_usage_id(
        request, course_id, usage_id)

    tracking_context_name = 'module_callback_handler'
    req = django_to_webob_request(request)
    try:
        with tracker.get_tracker().context(tracking_context_name,
                                           tracking_context):
            resp = instance.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.exception("XBlock %s attempted to access missing handler %r",
                      instance, handler)
        raise Http404

    # If we can't find the module, respond with a 404
    except NotFoundError:
        log.exception("Module indicating to user that request doesn't exist")
        raise Http404

    # For XModule-specific errors, we log the error and respond with an error message
    except ProcessingError as err:
        log.warning("Module encountered an error while processing AJAX call",
                    exc_info=True)
        return JsonResponse(object={'success': err.args[0]}, status=200)

    # If any other error occurred, re-raise it to trigger a 500 response
    except Exception:
        log.exception("error executing xblock handler")
        raise

    return webob_to_django_response(resp)
def xblock_handler(request,
                   course_key_string,
                   usage_key_string,
                   handler,
                   suffix=''):
    """
    Dispatch an AJAX action to an xblock

    Args:
        usage_id: The usage-id of the block to dispatch to
        handler (str): The handler to execute
        suffix (str): The remainder of the url to be passed to the handler

    Returns:
        :class:`django.http.HttpResponse`: The response from the handler, converted to a
            django response

    Example:
    POST ${STUDIO_URL}/sn-api/courses/{course_key}/xblocks/{usage_key}/handler/{handler}/

    See https://github.com/edx/edx-platform/blob/open-release/juniper.master/cms/djangoapps/contentstore/views/component.py#L449
    """
    usage_key = UsageKey.from_string(usage_key_string)

    # Let the module handle the AJAX
    req = django_to_webob_request(request)

    try:
        if is_xblock_aside(usage_key):
            # Get the descriptor for the block being wrapped by the aside (not the aside itself)
            descriptor = modulestore().get_item(usage_key.usage_key)
            handler_descriptor = get_aside_from_xblock(descriptor,
                                                       usage_key.aside_type)
            asides = [handler_descriptor]
        else:
            descriptor = modulestore().get_item(usage_key)
            handler_descriptor = descriptor
            asides = []
        handler_descriptor.xmodule_runtime = StudioEditModuleRuntime(
            request.user)
        resp = handler_descriptor.handle(handler, req, suffix)
    except NoSuchHandlerError:
        log.info(u"XBlock %s attempted to access missing handler %r",
                 handler_descriptor,
                 handler,
                 exc_info=True)
        raise Http404

    # unintentional update to handle any side effects of handle call
    # could potentially be updating actual course data or simply caching its values
    modulestore().update_item(descriptor, request.user.id, asides=asides)
    log.info('xblock content is updated (course_id: {}, xblock_id: {})'.format(
        course_key_string, usage_key_string))
    return webob_to_django_response(resp)
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix):
    """
    Invoke an XBlock handler, either authenticated or not.

    Arguments:
        request (HttpRequest): the current request
        course_id (str): A string of the form org/course/run
        usage_id (str): A string of the form i4x://org/course/category/name@revision
        handler (str): The name of the handler to invoke
        suffix (str): The suffix to pass to the handler when invoked
    """

    # Check submitted files
    files = request.FILES or {}
    error_msg = _check_files_limits(files)
    if error_msg:
        return JsonResponse(object={'success': error_msg}, status=413)

    instance, tracking_context = get_module_by_usage_id(request, course_id, usage_id)

    # Name the transaction so that we can view XBlock handlers separately in
    # New Relic. The suffix is necessary for XModule handlers because the
    # "handler" in those cases is always just "xmodule_handler".
    nr_tx_name = "{}.{}".format(instance.__class__.__name__, handler)
    nr_tx_name += "/{}".format(suffix) if suffix else ""
    newrelic.agent.set_transaction_name(nr_tx_name, group="Python/XBlock/Handler")

    tracking_context_name = 'module_callback_handler'
    req = django_to_webob_request(request)
    try:
        with tracker.get_tracker().context(tracking_context_name, tracking_context):
            resp = instance.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.exception("XBlock %s attempted to access missing handler %r", instance, handler)
        raise Http404

    # If we can't find the module, respond with a 404
    except NotFoundError:
        log.exception("Module indicating to user that request doesn't exist")
        raise Http404

    # For XModule-specific errors, we log the error and respond with an error message
    except ProcessingError as err:
        log.warning("Module encountered an error while processing AJAX call",
                    exc_info=True)
        return JsonResponse(object={'success': err.args[0]}, status=200)

    # If any other error occurred, re-raise it to trigger a 500 response
    except Exception:
        log.exception("error executing xblock handler")
        raise

    return webob_to_django_response(resp)
Beispiel #13
0
def handler(request, usage_id, handler_slug):
    """Provide a handler for the request."""
    student_id = get_student_id(request)
    log.info("Start handler %s/%s for student %s", usage_id, handler_slug, student_id)
    runtime = WorkbenchRuntime(student_id)
    block = runtime.get_block(usage_id)
    request = django_to_webob_request(request)
    request.path_info_pop()
    request.path_info_pop()
    result = block.runtime.handle(block, handler_slug, request)
    log.info("End handler %s/%s", usage_id, handler_slug)
    return webob_to_django_response(result)
Beispiel #14
0
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix):
    """
    Invoke an XBlock handler, either authenticated or not.

    Arguments:
        request (HttpRequest): the current request
        course_id (str): A string of the form org/course/run
        usage_id (str): A string of the form i4x://org/course/category/name@revision
        handler (str): The name of the handler to invoke
        suffix (str): The suffix to pass to the handler when invoked
    """

    # Check submitted files
    files = request.FILES or {}
    error_msg = _check_files_limits(files)
    if error_msg:
        return JsonResponse(object={'success': error_msg}, status=413)

    instance, tracking_context = _get_module_by_usage_id(request, course_id, usage_id)

    tracking_context_name = 'module_callback_handler'
    req = django_to_webob_request(request)
    try:
        with tracker.get_tracker().context(tracking_context_name, tracking_context):
            resp = instance.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.exception("XBlock %s attempted to access missing handler %r", instance, handler)
        raise Http404

    # If we can't find the module, respond with a 404
    except NotFoundError:
        log.exception("Module indicating to user that request doesn't exist")
        raise Http404

    # For XModule-specific errors, we log the error and respond with an error message
    except ProcessingError as err:
        log.warning("Module encountered an error while processing AJAX call",
                    exc_info=True)
        return JsonResponse(object={'success': err.args[0]}, status=200)

    # If any other error occurred, re-raise it to trigger a 500 response
    except Exception:
        log.exception("error executing xblock handler")
        raise

    return webob_to_django_response(resp)
Beispiel #15
0
def handler(request, usage_id, handler_slug, suffix=''):
    """Provide a handler for the request."""
    student_id = get_student_id(request)
    log.info("Start handler %s/%s for student %s", usage_id, handler_slug, student_id)
    runtime = WorkbenchRuntime(student_id)

    try:
        block = runtime.get_block(usage_id)
    except KeyError:
        raise Http404

    request = django_to_webob_request(request)
    request.path_info_pop()
    request.path_info_pop()
    result = block.runtime.handle(block, handler_slug, request, suffix)
    log.info("End handler %s/%s", usage_id, handler_slug)
    return webob_to_django_response(result)
Beispiel #16
0
def preview_handler(request, usage_key_string, handler, suffix=""):
    """
    Dispatch an AJAX action to an xblock

    usage_key_string: The usage_key_string-id of the block to dispatch to, passed through `quote_slashes`
    handler: The handler to execute
    suffix: The remainder of the url to be passed to the handler
    """
    usage_key = UsageKey.from_string(usage_key_string)

    if isinstance(usage_key, AsideUsageKeyV1):
        descriptor = modulestore().get_item(usage_key.usage_key)
        for aside in descriptor.runtime.get_asides(descriptor):
            if aside.scope_ids.block_type == usage_key.aside_type:
                asides = [aside]
                instance = aside
                break
    else:
        descriptor = modulestore().get_item(usage_key)
        instance = _load_preview_module(request, descriptor)
        asides = []

    # Let the module handle the AJAX
    req = django_to_webob_request(request)
    try:
        resp = instance.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.exception("XBlock %s attempted to access missing handler %r", instance, handler)
        raise Http404

    except NotFoundError:
        log.exception("Module indicating to user that request doesn't exist")
        raise Http404

    except ProcessingError:
        log.warning("Module raised an error while processing AJAX request", exc_info=True)
        return HttpResponseBadRequest()

    except Exception:
        log.exception("error processing ajax call")
        raise

    modulestore().update_item(descriptor, request.user.id, asides=asides)
    return webob_to_django_response(resp)
Beispiel #17
0
def component_handler(request, usage_key_string, handler, suffix=''):
    """
    Dispatch an AJAX action to an xblock

    Args:
        usage_id: The usage-id of the block to dispatch to
        handler (str): The handler to execute
        suffix (str): The remainder of the url to be passed to the handler

    Returns:
        :class:`django.http.HttpResponse`: The response from the handler, converted to a
            django response
    """
    usage_key = UsageKey.from_string(usage_key_string)

    # Let the module handle the AJAX
    req = django_to_webob_request(request)

    try:
        if is_xblock_aside(usage_key):
            # Get the descriptor for the block being wrapped by the aside (not the aside itself)
            descriptor = modulestore().get_item(usage_key.usage_key)
            handler_descriptor = get_aside_from_xblock(descriptor,
                                                       usage_key.aside_type)
            asides = [handler_descriptor]
        else:
            descriptor = modulestore().get_item(usage_key)
            handler_descriptor = descriptor
            asides = []
        handler_descriptor.xmodule_runtime = StudioEditModuleRuntime(
            request.user)
        resp = handler_descriptor.handle(handler, req, suffix)
    except NoSuchHandlerError:
        log.info(u"XBlock %s attempted to access missing handler %r",
                 handler_descriptor,
                 handler,
                 exc_info=True)
        raise Http404

    # unintentional update to handle any side effects of handle call
    # could potentially be updating actual course data or simply caching its values
    modulestore().update_item(descriptor, request.user.id, asides=asides)

    return webob_to_django_response(resp)
Beispiel #18
0
    def post(self, request, usage_key_string):
        """
        Dispatch an AJAX action to an xblock

        Args:
            usage_id: The usage-id of the block to dispatch to
            handler (str): The handler to execute
            suffix (str): The remainder of the url to be passed to the handler

        Returns:
            :class:`django.http.HttpResponse`: The response from the handler, converted to a
                django response
        """
        handler = 'submit_studio_edits'
        suffix = ''
        usage_key = UsageKey.from_string(usage_key_string)
        # Let the module handle the AJAX
        req = django_to_webob_request(request)

        asides = []

        try:
            if isinstance(usage_key, (AsideUsageKeyV1, AsideUsageKeyV2)):
                descriptor = modulestore().get_item(usage_key.usage_key)
                aside_instance = get_xblock_aside_instance(usage_key)
                asides = [aside_instance] if aside_instance else []
                resp = aside_instance.handle(handler, req, suffix)
            else:
                descriptor = modulestore().get_item(usage_key)
                descriptor.xmodule_runtime = StudioEditModuleRuntime(
                    request.user)
                resp = descriptor.handle(handler, req, suffix)
        except NoSuchHandlerError:
            raise Http404

        # unintentional update to handle any side effects of handle call
        # could potentially be updating actual course data or simply caching its values
        modulestore().update_item(descriptor, request.user.id, asides=asides)

        return webob_to_django_response(resp)
Beispiel #19
0
def handler(request, usage_id, handler_slug, suffix='', authenticated=True):
    """The view function for authenticated handler requests."""
    if authenticated:
        student_id = get_student_id(request)
        log.info("Start handler %s/%s for student %s", usage_id, handler_slug, student_id)
    else:
        student_id = "none"
        log.info("Start handler %s/%s", usage_id, handler_slug)

    runtime = WorkbenchRuntime(student_id)

    try:
        block = runtime.get_block(usage_id)
    except NoSuchUsage:
        raise Http404

    request = django_to_webob_request(request)
    request.path_info_pop()
    request.path_info_pop()
    result = block.runtime.handle(block, handler_slug, request, suffix)
    log.info("End handler %s/%s", usage_id, handler_slug)
    return webob_to_django_response(result)
Beispiel #20
0
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, course=None):
    """
    Invoke an XBlock handler, either authenticated or not.

    Arguments:
        request (HttpRequest): the current request
        course_id (str): A string of the form org/course/run
        usage_id (str): A string of the form i4x://org/course/category/name@revision
        handler (str): The name of the handler to invoke
        suffix (str): The suffix to pass to the handler when invoked
    """

    # Check submitted files
    files = request.FILES or {}
    error_msg = _check_files_limits(files)
    if error_msg:
        return JsonResponse({'success': error_msg}, status=413)

    # Make a CourseKey from the course_id, raising a 404 upon parse error.
    try:
        course_key = CourseKey.from_string(course_id)
    except InvalidKeyError:
        raise Http404

    set_custom_metrics_for_course_key(course_key)

    with modulestore().bulk_operations(course_key):
        instance, tracking_context = get_module_by_usage_id(request, course_id, usage_id, course=course)

        # Name the transaction so that we can view XBlock handlers separately in
        # New Relic. The suffix is necessary for XModule handlers because the
        # "handler" in those cases is always just "xmodule_handler".
        nr_tx_name = "{}.{}".format(instance.__class__.__name__, handler)
        nr_tx_name += "/{}".format(suffix) if (suffix and handler == "xmodule_handler") else ""
        set_monitoring_transaction_name(nr_tx_name, group="Python/XBlock/Handler")

        tracking_context_name = 'module_callback_handler'
        req = django_to_webob_request(request)
        try:
            with tracker.get_tracker().context(tracking_context_name, tracking_context):
                resp = instance.handle(handler, req, suffix)
                if suffix == 'problem_check' \
                        and course \
                        and getattr(course, 'entrance_exam_enabled', False) \
                        and getattr(instance, 'in_entrance_exam', False):
                    ee_data = {'entrance_exam_passed': user_has_passed_entrance_exam(request.user, course)}
                    resp = append_data_to_webob_response(resp, ee_data)

        except NoSuchHandlerError:
            log.exception("XBlock %s attempted to access missing handler %r", instance, handler)
            raise Http404

        # If we can't find the module, respond with a 404
        except NotFoundError:
            log.exception("Module indicating to user that request doesn't exist")
            raise Http404

        # For XModule-specific errors, we log the error and respond with an error message
        except ProcessingError as err:
            log.warning("Module encountered an error while processing AJAX call",
                        exc_info=True)
            return JsonResponse({'success': err.args[0]}, status=200)

        # If any other error occurred, re-raise it to trigger a 500 response
        except Exception:
            log.exception("error executing xblock handler")
            raise

    return webob_to_django_response(resp)
Beispiel #21
0
def handle_xblock_callback(request, course_id, usage_id, handler, suffix=None):
    """
    Generic view for extensions. This is where AJAX calls go.

    Arguments:

      - request -- the django request.
      - location -- the module location. Used to look up the XModule instance
      - course_id -- defines the course context for this request.

    Raises PermissionDenied if the user is not logged in. Raises Http404 if
    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.
    """
    location = unquote_slashes(usage_id)

    # Check parameters and fail fast if there's a problem
    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)
    if error_msg:
        return HttpResponse(json.dumps({'success': error_msg}))

    try:
        descriptor = modulestore().get_instance(course_id, location)
    except ItemNotFoundError:
        log.warn(
            "Invalid location for course id {course_id}: {location}".format(
                course_id=course_id,
                location=location
            )
        )
        raise Http404

    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
        course_id,
        request.user,
        descriptor
    )

    instance = get_module(request.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)
        raise Http404

    req = django_to_webob_request(request)
    try:
        resp = instance.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.exception("XBlock %s attempted to access missing handler %r", instance, handler)
        raise Http404

    # If we can't find the module, respond with a 404
    except NotFoundError:
        log.exception("Module indicating to user that request doesn't exist")
        raise Http404

    # For XModule-specific errors, we log the error and respond with an error message
    except ProcessingError as err:
        log.warning("Module encountered an error while processing AJAX call",
                    exc_info=True)
        return JsonResponse(object={'success': err.args[0]}, status=200)

    # If any other error occurred, re-raise it to trigger a 500 response
    except Exception:
        log.exception("error executing xblock handler")
        raise

    return webob_to_django_response(resp)
Beispiel #22
0
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix,
                           user):
    """
    Invoke an XBlock handler, either authenticated or not.

    Arguments:
        request (HttpRequest): the current request
        course_id (str): A string of the form org/course/run
        usage_id (str): A string of the form i4x://org/course/category/name@revision
        handler (str): The name of the handler to invoke
        suffix (str): The suffix to pass to the handler when invoked
        user (User): The currently logged in user

    """
    try:
        course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
        usage_key = course_id.make_usage_key_from_deprecated_string(
            unquote_slashes(usage_id))
    except InvalidKeyError:
        raise Http404("Invalid location")

    # Check submitted files
    files = request.FILES or {}
    error_msg = _check_files_limits(files)
    if error_msg:
        return HttpResponse(json.dumps({'success': error_msg}))

    try:
        descriptor = modulestore().get_item(usage_key)
    except ItemNotFoundError:
        log.warn(
            "Invalid location for course id {course_id}: {usage_key}".format(
                course_id=usage_key.course_key, usage_key=usage_key))
        raise Http404

    tracking_context_name = 'module_callback_handler'
    tracking_context = {
        'module': {
            'display_name': descriptor.display_name_with_default,
        }
    }

    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
        course_id, user, descriptor)
    instance = get_module(user,
                          request,
                          usage_key,
                          field_data_cache,
                          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?", usage_key,
                  user)
        raise Http404

    req = django_to_webob_request(request)
    try:
        with tracker.get_tracker().context(tracking_context_name,
                                           tracking_context):
            resp = instance.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.exception("XBlock %s attempted to access missing handler %r",
                      instance, handler)
        raise Http404

    # If we can't find the module, respond with a 404
    except NotFoundError:
        log.exception("Module indicating to user that request doesn't exist")
        raise Http404

    # For XModule-specific errors, we log the error and respond with an error message
    except ProcessingError as err:
        log.warning("Module encountered an error while processing AJAX call",
                    exc_info=True)
        return JsonResponse(object={'success': err.args[0]}, status=200)

    # If any other error occurred, re-raise it to trigger a 500 response
    except Exception:
        log.exception("error executing xblock handler")
        raise

    return webob_to_django_response(resp)
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, user):
    """
    Invoke an XBlock handler, either authenticated or not.

    Arguments:
        request (HttpRequest): the current request
        course_id (str): A string of the form org/course/run
        usage_id (str): A string of the form i4x://org/course/category/name@revision
        handler (str): The name of the handler to invoke
        suffix (str): The suffix to pass to the handler when invoked
        user (User): The currently logged in user

    """
    try:
        course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
        usage_key = course_id.make_usage_key_from_deprecated_string(unquote_slashes(usage_id))
    except InvalidKeyError:
        raise Http404("Invalid location")

    # Check submitted files
    files = request.FILES or {}
    error_msg = _check_files_limits(files)
    if error_msg:
        return HttpResponse(json.dumps({'success': error_msg}))

    try:
        descriptor = modulestore().get_item(usage_key)
    except ItemNotFoundError:
        log.warn(
            "Invalid location for course id {course_id}: {usage_key}".format(
                course_id=usage_key.course_key,
                usage_key=usage_key
            )
        )
        raise Http404

    tracking_context_name = 'module_callback_handler'
    tracking_context = {
        'module': {
            'display_name': descriptor.display_name_with_default,
        }
    }

    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
        course_id,
        user,
        descriptor
    )
    instance = get_module(user, request, usage_key, field_data_cache, 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?", usage_key, user)
        raise Http404

    req = django_to_webob_request(request)
    try:
        with tracker.get_tracker().context(tracking_context_name, tracking_context):
            resp = instance.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.exception("XBlock %s attempted to access missing handler %r", instance, handler)
        raise Http404

    # If we can't find the module, respond with a 404
    except NotFoundError:
        log.exception("Module indicating to user that request doesn't exist")
        raise Http404

    # For XModule-specific errors, we log the error and respond with an error message
    except ProcessingError as err:
        log.warning("Module encountered an error while processing AJAX call",
                    exc_info=True)
        return JsonResponse(object={'success': err.args[0]}, status=200)

    # If any other error occurred, re-raise it to trigger a 500 response
    except Exception:
        log.exception("error executing xblock handler")
        raise

    return webob_to_django_response(resp)
Beispiel #24
0
 def _as_django(self, *args, **kwargs):
     """
     Return a :class:`django.http.HttpResponse` created from a `webob.Response`
     initialized with `*args` and `**kwargs`
     """
     return webob_to_django_response(Response(*args, **kwargs))
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, course=None):
    """
    Invoke an XBlock handler, either authenticated or not.

    Arguments:
        request (HttpRequest): the current request
        course_id (str): A string of the form org/course/run
        usage_id (str): A string of the form i4x://org/course/category/name@revision
        handler (str): The name of the handler to invoke
        suffix (str): The suffix to pass to the handler when invoked
    """

    # Check submitted files
    files = request.FILES or {}
    error_msg = _check_files_limits(files)
    if error_msg:
        return JsonResponse({'success': error_msg}, status=413)

    # Make a CourseKey from the course_id, raising a 404 upon parse error.
    try:
        course_key = CourseKey.from_string(course_id)
    except InvalidKeyError:
        raise Http404

    # Gather metrics for New Relic so we can slice data in New Relic Insights
    newrelic.agent.add_custom_parameter('course_id', unicode(course_key))
    newrelic.agent.add_custom_parameter('org', unicode(course_key.org))

    with modulestore().bulk_operations(course_key):
        instance, tracking_context = get_module_by_usage_id(request, course_id, usage_id, course=course)

        # Name the transaction so that we can view XBlock handlers separately in
        # New Relic. The suffix is necessary for XModule handlers because the
        # "handler" in those cases is always just "xmodule_handler".
        nr_tx_name = "{}.{}".format(instance.__class__.__name__, handler)
        nr_tx_name += "/{}".format(suffix) if (suffix and handler == "xmodule_handler") else ""
        newrelic.agent.set_transaction_name(nr_tx_name, group="Python/XBlock/Handler")

        tracking_context_name = 'module_callback_handler'
        req = django_to_webob_request(request)
        try:
            with tracker.get_tracker().context(tracking_context_name, tracking_context):
                resp = instance.handle(handler, req, suffix)
                if suffix == 'problem_check' \
                        and course \
                        and getattr(course, 'entrance_exam_enabled', False) \
                        and getattr(instance, 'in_entrance_exam', False):
                    ee_data = {'entrance_exam_passed': user_has_passed_entrance_exam(request, course)}
                    resp = append_data_to_webob_response(resp, ee_data)

        except NoSuchHandlerError:
            log.exception("XBlock %s attempted to access missing handler %r", instance, handler)
            raise Http404

        # If we can't find the module, respond with a 404
        except NotFoundError:
            log.exception("Module indicating to user that request doesn't exist")
            raise Http404

        # For XModule-specific errors, we log the error and respond with an error message
        except ProcessingError as err:
            log.warning("Module encountered an error while processing AJAX call",
                        exc_info=True)
            return JsonResponse({'success': err.args[0]}, status=200)

        # If any other error occurred, re-raise it to trigger a 500 response
        except Exception:
            log.exception("error executing xblock handler")
            raise

    return webob_to_django_response(resp)
Beispiel #26
0
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)

    # Check parameters and fail fast if there's a problem
    if not Location.is_valid(location):
        raise Http404("Invalid location")

    # Check submitted files
    files = request.FILES or {}
    error_msg = _check_files_limits(files)
    if error_msg:
        return HttpResponse(json.dumps({'success': error_msg}))

    try:
        descriptor = modulestore().get_instance(course_id, location)
    except ItemNotFoundError:
        log.warn(
            "Invalid location for course id {course_id}: {location}".format(
                course_id=course_id, location=location))
        raise Http404

    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
        course_id, user, descriptor)
    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, user)
        raise Http404

    req = django_to_webob_request(request)
    try:
        resp = instance.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.exception("XBlock %s attempted to access missing handler %r",
                      instance, handler)
        raise Http404

    # If we can't find the module, respond with a 404
    except NotFoundError:
        log.exception("Module indicating to user that request doesn't exist")
        raise Http404

    # For XModule-specific errors, we log the error and respond with an error message
    except ProcessingError as err:
        log.warning("Module encountered an error while processing AJAX call",
                    exc_info=True)
        return JsonResponse(object={'success': err.args[0]}, status=200)

    # If any other error occurred, re-raise it to trigger a 500 response
    except Exception:
        log.exception("error executing xblock handler")
        raise

    return webob_to_django_response(resp)