Beispiel #1
0
    def test_error_conditions(self):
        """
        Verifies that exceptions are thrown in the expected cases.
        """
        with self.assertRaises(ValueError) as error:
            self.request.FILES = {"uploaded_file": SimpleUploadedFile("tempfile.csv", self.file_content)}
            store_uploaded_file(self.request, "wrong_key", [".txt", ".csv"], "stored_file", self.default_max_size)
        self.verify_exception("No file uploaded with key 'wrong_key'.", error)

        with self.assertRaises(exceptions.PermissionDenied) as error:
            self.request.FILES = {"uploaded_file": SimpleUploadedFile("tempfile.csv", self.file_content)}
            store_uploaded_file(self.request, "uploaded_file", [], "stored_file", self.default_max_size)
        self.verify_exception("The file must end with one of the following extensions: ''.", error)

        with self.assertRaises(exceptions.PermissionDenied) as error:
            self.request.FILES = {"uploaded_file": SimpleUploadedFile("tempfile.csv", self.file_content)}
            store_uploaded_file(self.request, "uploaded_file", [".bar"], "stored_file", self.default_max_size)
        self.verify_exception("The file must end with the extension '.bar'.", error)

        with self.assertRaises(exceptions.PermissionDenied) as error:
            self.request.FILES = {"uploaded_file": SimpleUploadedFile("tempfile.csv", self.file_content)}
            store_uploaded_file(self.request, "uploaded_file", [".xxx", ".bar"], "stored_file", self.default_max_size)
        self.verify_exception("The file must end with one of the following extensions: '.xxx', '.bar'.", error)

        with self.assertRaises(exceptions.PermissionDenied) as error:
            self.request.FILES = {"uploaded_file": SimpleUploadedFile("tempfile.csv", self.file_content)}
            store_uploaded_file(self.request, "uploaded_file", [".csv"], "stored_file", 2)
        self.verify_exception("Maximum upload file size is 2 bytes.", error)
Beispiel #2
0
    def test_validator(self):
        """
        Verify that a validator function can throw an exception.
        """
        validator_data = {}

        def verify_file_presence(should_exist):
            """ Verify whether or not the stored file, passed to the validator, exists. """
            self.assertEqual(
                should_exist,
                validator_data["storage"].exists(validator_data["filename"]))

        def store_file_data(storage, filename):
            """ Stores file validator data for testing after validation is complete. """
            validator_data["storage"] = storage
            validator_data["filename"] = filename
            verify_file_presence(True)

        def exception_validator(storage, filename):
            """ Validation test function that throws an exception """
            self.assertEqual("error_file.csv", os.path.basename(filename))
            with storage.open(filename, 'rb') as f:
                self.assertEqual(self.file_content, f.read())
            store_file_data(storage, filename)
            raise FileValidationException("validation failed")

        def success_validator(storage, filename):
            """ Validation test function that is a no-op """
            self.assertIn("success_file", os.path.basename(filename))
            store_file_data(storage, filename)

        with self.assertRaises(FileValidationException) as error:
            self.request.FILES = {
                "uploaded_file":
                SimpleUploadedFile("tempfile.csv", self.file_content)
            }
            store_uploaded_file(self.request,
                                "uploaded_file", [".csv"],
                                "error_file",
                                self.default_max_size,
                                validator=exception_validator)
        self.verify_exception("validation failed", error)
        # Verify the file was deleted.
        verify_file_presence(False)

        self.request.FILES = {
            "uploaded_file": SimpleUploadedFile("tempfile.csv",
                                                self.file_content)
        }
        store_uploaded_file(self.request,
                            "uploaded_file", [".csv"],
                            "success_file",
                            self.default_max_size,
                            validator=success_validator)
        # Verify the file still exists
        verify_file_presence(True)
Beispiel #3
0
    def post(self, request, course_id):
        """
        Handles a file upload.
        """
        thread_key = request.POST.get("thread_key", "root")
        unique_file_name = f"{course_id}/{thread_key}/{uuid.uuid4()}"
        try:
            file_storage, stored_file_name = store_uploaded_file(
                request,
                "uploaded_file",
                cc_settings.ALLOWED_UPLOAD_FILE_TYPES,
                unique_file_name,
                max_file_size=cc_settings.MAX_UPLOAD_FILE_SIZE,
            )
        except ValueError as err:
            raise BadRequest("no `uploaded_file` was provided") from err

        file_absolute_url = file_storage.url(stored_file_name)

        # this is a no-op in production, but is required in development,
        # since the filesystem storage returns the path without a base_url
        file_absolute_url = request.build_absolute_uri(file_absolute_url)

        return Response(
            {"location": file_absolute_url},
            content_type="application/json",
        )
Beispiel #4
0
def upload(request, course_id):  # ajax upload file to a question or answer  # lint-amnesty, pylint: disable=unused-argument
    """view that handles file upload via Ajax
    """

    # check upload permission
    error = ''
    new_file_name = ''
    try:
        # TODO authorization
        #may raise exceptions.PermissionDenied
        #if request.user.is_anonymous:
        #    msg = _('Sorry, anonymous users cannot upload files')
        #    raise exceptions.PermissionDenied(msg)

        #request.user.assert_can_upload_file()

        base_file_name = str(time.time()).replace(
            '.', str(random.randint(0, 100000)))
        file_storage, new_file_name = store_uploaded_file(
            request,
            'file-upload',
            cc_settings.ALLOWED_UPLOAD_FILE_TYPES,
            base_file_name,
            max_file_size=cc_settings.MAX_UPLOAD_FILE_SIZE)

    except exceptions.PermissionDenied as err:
        error = str(err)
    except Exception as err:  # pylint: disable=broad-except
        print(err)
        logging.critical(str(err))
        error = _(
            'Error uploading file. Please contact the site administrator. Thank you.'
        )

    if error == '':
        result = _('Good')
        file_url = file_storage.url(new_file_name)
        parsed_url = six.moves.urllib.parse.urlparse(file_url)
        file_url = six.moves.urllib.parse.urlunparse(
            six.moves.urllib.parse.ParseResult(parsed_url.scheme,
                                               parsed_url.netloc,
                                               parsed_url.path, '', '', ''))
    else:
        result = ''
        file_url = ''

    # Using content-type of text/plain here instead of JSON because
    # IE doesn't know how to handle the JSON response and prompts the
    # user to save the JSON as a file instead of passing it to the callback.
    return HttpResponse(
        json.dumps({  # lint-amnesty, pylint: disable=http-response-with-json-dumps
            'result': {
                'msg': result,
                'error': error,
                'file_url': file_url,
            }
        }),
        content_type="text/plain")
Beispiel #5
0
 def test_file_upload_lower_case_extension(self):
     """
     Tests uploading a file with lower case extension. Verifies that the stored file contents are correct.
     """
     self.request.FILES = {"uploaded_file": SimpleUploadedFile("tempfile.csv", self.file_content)}
     file_storage, stored_file_name = store_uploaded_file(
         self.request, "uploaded_file", [".csv"], "stored_file", self.default_max_size
     )
     self._verify_successful_upload(file_storage, stored_file_name, self.file_content)
Beispiel #6
0
    def test_unique_filenames(self):
        """
        Test that the file storage method will create a unique filename if the file already exists.
        """
        requested_file_name = "nonunique_store"
        file_content = b"copy"

        self.request.FILES = {"nonunique_file": SimpleUploadedFile("nonunique.txt", file_content)}
        _, first_stored_file_name = store_uploaded_file(
            self.request, "nonunique_file", [".txt"], requested_file_name, self.default_max_size
        )

        self.request.FILES = {"nonunique_file": SimpleUploadedFile("nonunique.txt", file_content)}
        file_storage, second_stored_file_name = store_uploaded_file(
            self.request, "nonunique_file", [".txt"], requested_file_name, self.default_max_size
        )
        self.assertNotEqual(first_stored_file_name, second_stored_file_name)
        self.assertIn(requested_file_name, second_stored_file_name)
        self._verify_successful_upload(file_storage, second_stored_file_name, file_content)