def test_request_token(self):
        """
        Verify that a proper token is returned.
        """
        request_with_token = RequestFactory().get('/')
        request_with_token._xblock_token = '123'  # pylint: disable=protected-access
        token = request_token(request_with_token)
        self.assertEqual(token, '123')

        request_without_token = RequestFactory().get('/')
        token = request_token(request_without_token)
        # Test to see if the token is an uuid1 hex value
        test_uuid = uuid.UUID(token, version=1)
        self.assertEqual(token, test_uuid.hex)
Exemple #2
0
    def test_request_token(self):
        """
        Verify that a proper token is returned.
        """
        request_with_token = RequestFactory().get('/')
        request_with_token._xblock_token = '123'  # pylint: disable=protected-access
        token = request_token(request_with_token)
        self.assertEqual(token, '123')

        request_without_token = RequestFactory().get('/')
        token = request_token(request_without_token)
        # Test to see if the token is an uuid1 hex value
        test_uuid = uuid.UUID(token, version=1)
        self.assertEqual(token, test_uuid.hex)
def get_module_for_descriptor(user,
                              request,
                              descriptor,
                              field_data_cache,
                              course_key,
                              position=None,
                              wrap_xmodule_display=True,
                              grade_bucket_type=None,
                              static_asset_path=''):
    """
    Implements get_module, extracting out the request-specific functionality.

    See get_module() docstring for further details.
    """
    track_function = make_track_function(request)
    xqueue_callback_url_prefix = get_xqueue_callback_url_prefix(request)

    user_location = getattr(request, 'session', {}).get('country_code')

    return get_module_for_descriptor_internal(
        user=user,
        descriptor=descriptor,
        field_data_cache=field_data_cache,
        course_id=course_key,
        track_function=track_function,
        xqueue_callback_url_prefix=xqueue_callback_url_prefix,
        position=position,
        wrap_xmodule_display=wrap_xmodule_display,
        grade_bucket_type=grade_bucket_type,
        static_asset_path=static_asset_path,
        user_location=user_location,
        request_token=request_token(request),
    )
def _preview_module_system(request, descriptor, field_data):
    """
    Returns a ModuleSystem for the specified descriptor that is specialized for
    rendering module previews.

    request: The active django request
    descriptor: An XModuleDescriptor
    """

    course_id = descriptor.location.course_key
    display_name_only = (descriptor.category == 'static_tab')

    wrappers = [
        # This wrapper wraps the module in the template specified above
        partial(
            wrap_xblock,
            'PreviewRuntime',
            display_name_only=display_name_only,
            usage_id_serializer=unicode,
            request_token=request_token(request)
        ),

        # This wrapper replaces urls in the output that start with /static
        # with the correct course-specific url for the static content
        partial(replace_static_urls, None, course_id=course_id),
        _studio_wrap_xblock,
    ]

    descriptor.runtime._services['studio_user_permissions'] = StudioPermissionsService(request)  # pylint: disable=protected-access

    return PreviewModuleSystem(
        static_url=settings.STATIC_URL,
        # TODO (cpennington): Do we want to track how instructors are using the preview problems?
        track_function=lambda event_type, event: None,
        filestore=descriptor.runtime.resources_fs,
        get_module=partial(_load_preview_module, request),
        render_template=render_from_lms,
        debug=True,
        replace_urls=partial(static_replace.replace_static_urls, data_directory=None, course_id=course_id),
        user=request.user,
        can_execute_unsafe_code=(lambda: can_execute_unsafe_code(course_id)),
        get_python_lib_zip=(lambda: get_python_lib_zip(contentstore, course_id)),
        mixins=settings.XBLOCK_MIXINS,
        course_id=course_id,
        anonymous_student_id='student',

        # Set up functions to modify the fragment produced by student_view
        wrappers=wrappers,
        error_descriptor_class=ErrorDescriptor,
        get_user_role=lambda: get_user_role(request.user, course_id),
        # Get the raw DescriptorSystem, not the CombinedSystem
        descriptor_runtime=descriptor._runtime,  # pylint: disable=protected-access
        services={
            "i18n": ModuleI18nService(),
            "field-data": field_data,
            "library_tools": LibraryToolsService(modulestore()),
            "settings": SettingsService(),
            "user": DjangoXBlockUserService(request.user),
        },
    )
def get_module_for_descriptor(user, request, descriptor, field_data_cache, course_key,
                              position=None, wrap_xmodule_display=True, grade_bucket_type=None,
                              static_asset_path=''):
    """
    Implements get_module, extracting out the request-specific functionality.

    See get_module() docstring for further details.
    """
    track_function = make_track_function(request)
    xqueue_callback_url_prefix = get_xqueue_callback_url_prefix(request)

    user_location = getattr(request, 'session', {}).get('country_code')

    return get_module_for_descriptor_internal(
        user=user,
        descriptor=descriptor,
        field_data_cache=field_data_cache,
        course_id=course_key,
        track_function=track_function,
        xqueue_callback_url_prefix=xqueue_callback_url_prefix,
        position=position,
        wrap_xmodule_display=wrap_xmodule_display,
        grade_bucket_type=grade_bucket_type,
        static_asset_path=static_asset_path,
        user_location=user_location,
        request_token=request_token(request),
    )
Exemple #6
0
def _preview_module_system(request, descriptor, field_data):
    """
    Returns a ModuleSystem for the specified descriptor that is specialized for
    rendering module previews.

    request: The active django request
    descriptor: An XModuleDescriptor
    """

    course_id = descriptor.location.course_key
    display_name_only = (descriptor.category == 'static_tab')

    replace_url_service = ReplaceURLService(course_id=course_id)

    wrappers = [
        # This wrapper wraps the module in the template specified above
        partial(wrap_xblock,
                'PreviewRuntime',
                display_name_only=display_name_only,
                usage_id_serializer=str,
                request_token=request_token(request)),

        # This wrapper replaces urls in the output that start with /static
        # with the correct course-specific url for the static content
        partial(replace_urls_wrapper,
                replace_url_service=replace_url_service,
                static_replace_only=True),
        _studio_wrap_xblock,
    ]

    wrappers_asides = [
        partial(wrap_xblock_aside,
                'PreviewRuntime',
                usage_id_serializer=str,
                request_token=request_token(request))
    ]

    mako_service = MakoService(namespace_prefix='lms.')
    if settings.FEATURES.get("LICENSING", False):
        # stick the license wrapper in front
        wrappers.insert(0, partial(wrap_with_license,
                                   mako_service=mako_service))

    return PreviewModuleSystem(
        static_url=settings.STATIC_URL,
        # TODO (cpennington): Do we want to track how instructors are using the preview problems?
        track_function=lambda event_type, event: None,
        get_module=partial(_load_preview_module, request),
        debug=True,
        mixins=settings.XBLOCK_MIXINS,
        course_id=course_id,

        # Set up functions to modify the fragment produced by student_view
        wrappers=wrappers,
        wrappers_asides=wrappers_asides,
        error_descriptor_class=ErrorBlock,
        # Get the raw DescriptorSystem, not the CombinedSystem
        descriptor_runtime=descriptor._runtime,  # pylint: disable=protected-access
        services={
            "field-data":
            field_data,
            "i18n":
            ModuleI18nService,
            'mako':
            mako_service,
            "settings":
            SettingsService(),
            "user":
            DjangoXBlockUserService(
                request.user,
                anonymous_user_id='student',
                user_role=get_user_role(request.user, course_id),
            ),
            "partitions":
            StudioPartitionService(course_id=course_id),
            "teams_configuration":
            TeamsConfigurationService(),
            "sandbox":
            SandboxService(contentstore=contentstore, course_id=course_id),
            "cache":
            CacheService(cache),
            'replace_urls':
            replace_url_service
        },
    )
Exemple #7
0
def xblock_view_handler(request, usage_key_string, view_name):
    """
    The restful handler for requests for rendered xblock views.

    Returns a json object containing two keys:
        html: The rendered html of the view
        resources: A list of tuples where the first element is the resource hash, and
            the second is the resource description
    """
    usage_key = usage_key_with_run(usage_key_string)
    if not has_studio_read_access(request.user, usage_key.course_key):
        raise PermissionDenied()

    accept_header = request.META.get('HTTP_ACCEPT', 'application/json')

    if 'application/json' in accept_header:
        store = modulestore()
        xblock = store.get_item(usage_key)
        container_views = ['container_preview', 'reorderable_container_child_preview', 'container_child_preview']

        # wrap the generated fragment in the xmodule_editor div so that the javascript
        # can bind to it correctly
        xblock.runtime.wrappers.append(partial(
            wrap_xblock,
            'StudioRuntime',
            usage_id_serializer=unicode,
            request_token=request_token(request),
        ))

        if view_name in (STUDIO_VIEW, VISIBILITY_VIEW):
            try:
                fragment = xblock.render(view_name)
            # catch exceptions indiscriminately, since after this point they escape the
            # dungeon and surface as uneditable, unsaveable, and undeletable
            # component-goblins.
            except Exception as exc:                          # pylint: disable=broad-except
                log.debug("Unable to render %s for %r", view_name, xblock, exc_info=True)
                fragment = Fragment(render_to_string('html_error.html', {'message': str(exc)}))

        elif view_name in PREVIEW_VIEWS + container_views:
            is_pages_view = view_name == STUDENT_VIEW   # Only the "Pages" view uses student view in Studio
            can_edit = has_studio_write_access(request.user, usage_key.course_key)

            # Determine the items to be shown as reorderable. Note that the view
            # 'reorderable_container_child_preview' is only rendered for xblocks that
            # are being shown in a reorderable container, so the xblock is automatically
            # added to the list.
            reorderable_items = set()
            if view_name == 'reorderable_container_child_preview':
                reorderable_items.add(xblock.location)

            paging = None
            try:
                if request.REQUEST.get('enable_paging', 'false') == 'true':
                    paging = {
                        'page_number': int(request.REQUEST.get('page_number', 0)),
                        'page_size': int(request.REQUEST.get('page_size', 0)),
                    }
            except ValueError:
                # pylint: disable=too-many-format-args
                return HttpResponse(
                    content="Couldn't parse paging parameters: enable_paging: "
                            "{0}, page_number: {1}, page_size: {2}".format(
                                request.REQUEST.get('enable_paging', 'false'),
                                request.REQUEST.get('page_number', 0),
                                request.REQUEST.get('page_size', 0)
                            ),
                    status=400,
                    content_type="text/plain",
                )

            force_render = request.REQUEST.get('force_render', None)

            # Set up the context to be passed to each XBlock's render method.
            context = {
                'is_pages_view': is_pages_view,     # This setting disables the recursive wrapping of xblocks
                'is_unit_page': is_unit(xblock),
                'can_edit': can_edit,
                'root_xblock': xblock if (view_name == 'container_preview') else None,
                'reorderable_items': reorderable_items,
                'paging': paging,
                'force_render': force_render,
            }

            fragment = get_preview_fragment(request, xblock, context)

            # Note that the container view recursively adds headers into the preview fragment,
            # so only the "Pages" view requires that this extra wrapper be included.
            if is_pages_view:
                fragment.content = render_to_string('component.html', {
                    'xblock_context': context,
                    'xblock': xblock,
                    'locator': usage_key,
                    'preview': fragment.content,
                    'label': xblock.display_name or xblock.scope_ids.block_type,
                })
        else:
            raise Http404

        hashed_resources = OrderedDict()
        for resource in fragment.resources:
            hashed_resources[hash_resource(resource)] = resource

        return JsonResponse({
            'html': fragment.content,
            'resources': hashed_resources.items()
        })

    else:
        return HttpResponse(status=406)
Exemple #8
0
def _preview_module_system(request, descriptor, field_data):
    """
    Returns a ModuleSystem for the specified descriptor that is specialized for
    rendering module previews.

    request: The active django request
    descriptor: An XModuleDescriptor
    """

    course_id = descriptor.location.course_key
    display_name_only = (descriptor.category == 'static_tab')

    wrappers = [
        # This wrapper wraps the module in the template specified above
        partial(wrap_xblock,
                'PreviewRuntime',
                display_name_only=display_name_only,
                usage_id_serializer=unicode,
                request_token=request_token(request)),

        # This wrapper replaces urls in the output that start with /static
        # with the correct course-specific url for the static content
        partial(replace_static_urls, None, course_id=course_id),
        _studio_wrap_xblock,
    ]

    wrappers_asides = [
        partial(wrap_xblock_aside,
                'PreviewRuntime',
                usage_id_serializer=unicode,
                request_token=request_token(request))
    ]

    if settings.FEATURES.get("LICENSING", False):
        # stick the license wrapper in front
        wrappers.insert(0, wrap_with_license)

    return PreviewModuleSystem(
        static_url=settings.STATIC_URL,
        # TODO (cpennington): Do we want to track how instructors are using the preview problems?
        track_function=lambda event_type, event: None,
        filestore=descriptor.runtime.resources_fs,
        get_module=partial(_load_preview_module, request),
        render_template=render_from_lms,
        debug=True,
        replace_urls=partial(static_replace.replace_static_urls,
                             data_directory=None,
                             course_id=course_id),
        user=request.user,
        can_execute_unsafe_code=(lambda: can_execute_unsafe_code(course_id)),
        get_python_lib_zip=(
            lambda: get_python_lib_zip(contentstore, course_id)),
        mixins=settings.XBLOCK_MIXINS,
        course_id=course_id,
        anonymous_student_id='student',

        # Set up functions to modify the fragment produced by student_view
        wrappers=wrappers,
        wrappers_asides=wrappers_asides,
        error_descriptor_class=ErrorDescriptor,
        get_user_role=lambda: get_user_role(request.user, course_id),
        # Get the raw DescriptorSystem, not the CombinedSystem
        descriptor_runtime=descriptor._runtime,  # pylint: disable=protected-access
        services={
            "field-data": field_data,
            "i18n": ModuleI18nService,
            "settings": SettingsService(),
            "user": DjangoXBlockUserService(request.user),
            "partitions": StudioPartitionService(course_id=course_id)
        },
    )
def _preview_module_system(request, descriptor, field_data):
    """
    Returns a ModuleSystem for the specified descriptor that is specialized for
    rendering module previews.

    request: The active django request
    descriptor: An XModuleDescriptor
    """

    course_id = descriptor.location.course_key
    display_name_only = (descriptor.category == 'static_tab')

    wrappers = [
        # This wrapper wraps the module in the template specified above
        partial(
            wrap_xblock,
            'PreviewRuntime',
            display_name_only=display_name_only,
            usage_id_serializer=unicode,
            request_token=request_token(request)
        ),

        # This wrapper replaces urls in the output that start with /static
        # with the correct course-specific url for the static content
        partial(replace_static_urls, None, course_id=course_id),
        _studio_wrap_xblock,
    ]

    wrappers_asides = [
        partial(
            wrap_xblock_aside,
            'PreviewRuntime',
            usage_id_serializer=unicode,
            request_token=request_token(request)
        )
    ]

    if settings.FEATURES.get("LICENSING", False):
        # stick the license wrapper in front
        wrappers.insert(0, wrap_with_license)

    services = get_available_xblock_services(request, field_data, course_id)

    return PreviewModuleSystem(
        static_url=settings.STATIC_URL,
        # TODO (cpennington): Do we want to track how instructors are using the preview problems?
        track_function=lambda event_type, event: None,
        filestore=descriptor.runtime.resources_fs,
        get_module=partial(_load_preview_module, request),
        render_template=render_from_lms,
        debug=True,
        replace_urls=partial(static_replace.replace_static_urls, data_directory=None, course_id=course_id),
        user=request.user,
        can_execute_unsafe_code=(lambda: can_execute_unsafe_code(course_id)),
        get_python_lib_zip=(lambda: get_python_lib_zip(contentstore, course_id)),
        mixins=settings.XBLOCK_MIXINS,
        course_id=course_id,
        anonymous_student_id='student',

        # Set up functions to modify the fragment produced by student_view
        wrappers=wrappers,
        wrappers_asides=wrappers_asides,
        error_descriptor_class=ErrorDescriptor,
        get_user_role=lambda: get_user_role(request.user, course_id),
        # Get the raw DescriptorSystem, not the CombinedSystem
        descriptor_runtime=descriptor._runtime,  # pylint: disable=protected-access
        services=services,
    )
Exemple #10
0
def xblock_view_handler(request, usage_key_string, view_name):
    """
    The restful handler for requests for rendered xblock views.

    Returns a json object containing two keys:
        html: The rendered html of the view
        resources: A list of tuples where the first element is the resource hash, and
            the second is the resource description
    """
    usage_key = usage_key_with_run(usage_key_string)
    if not has_studio_read_access(request.user, usage_key.course_key):
        raise PermissionDenied()

    accept_header = request.META.get('HTTP_ACCEPT', 'application/json')

    if 'application/json' in accept_header:
        store = modulestore()
        xblock = store.get_item(usage_key)
        container_views = [
            'container_preview', 'reorderable_container_child_preview',
            'container_child_preview'
        ]

        # wrap the generated fragment in the xmodule_editor div so that the javascript
        # can bind to it correctly
        xblock.runtime.wrappers.append(
            partial(
                wrap_xblock,
                'StudioRuntime',
                usage_id_serializer=unicode,
                request_token=request_token(request),
            ))

        if view_name in (STUDIO_VIEW, VISIBILITY_VIEW):
            try:
                fragment = xblock.render(view_name)
            # catch exceptions indiscriminately, since after this point they escape the
            # dungeon and surface as uneditable, unsaveable, and undeletable
            # component-goblins.
            except Exception as exc:  # pylint: disable=broad-except
                log.debug("Unable to render %s for %r",
                          view_name,
                          xblock,
                          exc_info=True)
                fragment = Fragment(
                    render_to_string('html_error.html', {'message': str(exc)}))

        elif view_name in (PREVIEW_VIEWS + container_views):
            is_pages_view = view_name == STUDENT_VIEW  # Only the "Pages" view uses student view in Studio
            can_edit = has_studio_write_access(request.user,
                                               usage_key.course_key)

            # Determine the items to be shown as reorderable. Note that the view
            # 'reorderable_container_child_preview' is only rendered for xblocks that
            # are being shown in a reorderable container, so the xblock is automatically
            # added to the list.
            reorderable_items = set()
            if view_name == 'reorderable_container_child_preview':
                reorderable_items.add(xblock.location)

            paging = None
            try:
                if request.REQUEST.get('enable_paging', 'false') == 'true':
                    paging = {
                        'page_number':
                        int(request.REQUEST.get('page_number', 0)),
                        'page_size': int(request.REQUEST.get('page_size', 0)),
                    }
            except ValueError:
                # pylint: disable=too-many-format-args
                return HttpResponse(
                    content="Couldn't parse paging parameters: enable_paging: "
                    "{0}, page_number: {1}, page_size: {2}".format(
                        request.REQUEST.get('enable_paging', 'false'),
                        request.REQUEST.get('page_number', 0),
                        request.REQUEST.get('page_size', 0)),
                    status=400,
                    content_type="text/plain",
                )

            force_render = request.REQUEST.get('force_render', None)

            # Set up the context to be passed to each XBlock's render method.
            context = {
                'is_pages_view':
                is_pages_view,  # This setting disables the recursive wrapping of xblocks
                'is_unit_page': is_unit(xblock),
                'can_edit': can_edit,
                'root_xblock': xblock if
                (view_name == 'container_preview') else None,
                'reorderable_items': reorderable_items,
                'paging': paging,
                'force_render': force_render,
            }

            fragment = get_preview_fragment(request, xblock, context)

            # Note that the container view recursively adds headers into the preview fragment,
            # so only the "Pages" view requires that this extra wrapper be included.
            if is_pages_view:
                fragment.content = render_to_string(
                    'component.html', {
                        'xblock_context':
                        context,
                        'xblock':
                        xblock,
                        'locator':
                        usage_key,
                        'preview':
                        fragment.content,
                        'label':
                        xblock.display_name or xblock.scope_ids.block_type,
                    })
        else:
            raise Http404

        hashed_resources = OrderedDict()
        for resource in fragment.resources:
            hashed_resources[hash_resource(resource)] = resource

        return JsonResponse({
            'html': fragment.content,
            'resources': hashed_resources.items()
        })

    else:
        return HttpResponse(status=406)