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 _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 }, )
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)
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, )
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)