def get_module_by_usage_id(request, course_id, usage_id, disable_staff_debug_info=False, course=None): """ Gets a module instance based on its `usage_id` in a course, for a given request/user Returns (instance, tracking_context) """ user = request.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") try: descriptor = modulestore().get_item(usage_key) descriptor_orig_usage_key, descriptor_orig_version = modulestore().get_block_original_usage(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 = { 'module': { 'display_name': descriptor.display_name_with_default, 'usage_key': unicode(descriptor.location), } } # For blocks that are inherited from a content library, we add some additional metadata: if descriptor_orig_usage_key is not None: tracking_context['module']['original_usage_key'] = unicode(descriptor_orig_usage_key) tracking_context['module']['original_usage_version'] = unicode(descriptor_orig_version) field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course_id, user, descriptor ) setup_masquerade(request, course_id, has_access(user, 'staff', descriptor, course_id)) instance = get_module_for_descriptor( user, request, descriptor, field_data_cache, usage_key.course_key, disable_staff_debug_info=disable_staff_debug_info, course=course ) 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 return (instance, tracking_context)
def post(self, request): """ POST /api/bookmarks/v1/bookmarks/ Request data: {"usage_id": "<usage-id>"} """ if not request.data: return self.error_response(ugettext_noop(u"No data provided."), DEFAULT_USER_MESSAGE) usage_id = request.data.get("usage_id", None) if not usage_id: return self.error_response(ugettext_noop(u"Parameter usage_id not provided."), DEFAULT_USER_MESSAGE) try: usage_key = UsageKey.from_string(unquote_slashes(usage_id)) except InvalidKeyError: error_message = ugettext_noop(u"Invalid usage_id: {usage_id}.").format(usage_id=usage_id) log.error(error_message) return self.error_response(error_message, DEFAULT_USER_MESSAGE) try: bookmark = api.create_bookmark(user=self.request.user, usage_key=usage_key) except ItemNotFoundError: error_message = ugettext_noop(u"Block with usage_id: {usage_id} not found.").format(usage_id=usage_id) log.error(error_message) return self.error_response(error_message, DEFAULT_USER_MESSAGE) except BookmarksLimitReachedError: error_message = ugettext_noop( u"You can create up to {max_num_bookmarks_per_course} bookmarks." u" You must remove some bookmarks before you can add new ones." ).format(max_num_bookmarks_per_course=settings.MAX_BOOKMARKS_PER_COURSE) log.info(u"Attempted to create more than %s bookmarks", settings.MAX_BOOKMARKS_PER_COURSE) return self.error_response(error_message) return Response(bookmark, status=status.HTTP_201_CREATED)
def get_module_by_usage_id(request, course_id, usage_id, disable_staff_debug_info=False, course=None): """ Gets a module instance based on its `usage_id` in a course, for a given request/user Returns (instance, tracking_context) """ user = request.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") try: descriptor = modulestore().get_item(usage_key) descriptor_orig_usage_key, descriptor_orig_version = modulestore().get_block_original_usage(usage_key) except ItemNotFoundError: log.warn( "Invalid location for course id %s: %s", usage_key.course_key, usage_key ) raise Http404 tracking_context = { 'module': { 'display_name': descriptor.display_name_with_default_escaped, 'usage_key': unicode(descriptor.location), } } # For blocks that are inherited from a content library, we add some additional metadata: if descriptor_orig_usage_key is not None: tracking_context['module']['original_usage_key'] = unicode(descriptor_orig_usage_key) tracking_context['module']['original_usage_version'] = unicode(descriptor_orig_version) unused_masquerade, user = setup_masquerade(request, course_id, has_access(user, 'staff', descriptor, course_id)) field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course_id, user, descriptor ) instance = get_module_for_descriptor( user, request, descriptor, field_data_cache, usage_key.course_key, disable_staff_debug_info=disable_staff_debug_info, course=course ) 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 return (instance, tracking_context)
def post(self, request): """ POST /api/bookmarks/v1/bookmarks/ Request data: {"usage_id": "<usage-id>"} """ if not request.data: return self.error_response(ugettext_noop(u'No data provided.'), DEFAULT_USER_MESSAGE) usage_id = request.data.get('usage_id', None) if not usage_id: return self.error_response( ugettext_noop(u'Parameter usage_id not provided.'), DEFAULT_USER_MESSAGE) try: usage_key = UsageKey.from_string(unquote_slashes(usage_id)) except InvalidKeyError: error_message = ugettext_noop( u'Invalid usage_id: {usage_id}.').format(usage_id=usage_id) log.error(error_message) return self.error_response(error_message, DEFAULT_USER_MESSAGE) try: bookmark = api.create_bookmark(user=self.request.user, usage_key=usage_key) except ItemNotFoundError: error_message = ugettext_noop( u'Block with usage_id: {usage_id} not found.').format( usage_id=usage_id) log.error(error_message) return self.error_response(error_message, DEFAULT_USER_MESSAGE) except BookmarksLimitReachedError: error_message = ugettext_noop( u'You can create up to {max_num_bookmarks_per_course} bookmarks.' u' You must remove some bookmarks before you can add new ones.' ).format( max_num_bookmarks_per_course=settings.MAX_BOOKMARKS_PER_COURSE) log.info(u'Attempted to create more than %s bookmarks', settings.MAX_BOOKMARKS_PER_COURSE) return self.error_response(error_message) return Response(bookmark, status=status.HTTP_201_CREATED)
def test_inverse(self, test_string): self.assertEquals(test_string, unquote_slashes(quote_slashes(test_string)))
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) descriptor_orig_usage_key, descriptor_orig_version = modulestore( ).get_block_original_usage(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, 'usage_key': unicode(descriptor.location), } } # For blocks that are inherited from a content library, we add some additional metadata: if descriptor_orig_usage_key is not None: tracking_context['module']['original_usage_key'] = unicode( descriptor_orig_usage_key) tracking_context['module']['original_usage_version'] = unicode( descriptor_orig_version) field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course_id, user, descriptor) setup_masquerade(request, course_id, has_access(user, 'staff', descriptor, course_id)) 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)