コード例 #1
0
def test_inconsistent_chunks_rfc7233(rf: RequestFactory):
    widget = AjaxUploadWidget(ajax_target_path="/ajax")
    widget.timeout = timedelta(seconds=1)
    content = load_test_data()
    # Overlapping chunks
    upload_id = generate_new_upload_id(
        test_inconsistent_chunks_rfc7233, content
    )
    part_1 = create_partial_upload_file_request(rf, upload_id, content, 0, 10)
    part_2 = create_partial_upload_file_request(rf, upload_id, content, 5, 15)
    widget.handle_ajax(part_1)
    assert isinstance(widget.handle_ajax(part_2), HttpResponseBadRequest)
    # Inconsistent filenames
    upload_id += "x"
    part_1 = create_partial_upload_file_request(
        rf, upload_id, content, 0, 10, filename="a"
    )
    part_2 = create_partial_upload_file_request(
        rf, upload_id, content, 10, 20, filename="b"
    )
    widget.handle_ajax(part_1)
    assert isinstance(widget.handle_ajax(part_2), HttpResponseBadRequest)
    # Inconsistent total size
    upload_id += "x"
    part_1 = create_partial_upload_file_request(
        rf, upload_id, content[:20], 0, 10
    )
    part_2 = create_partial_upload_file_request(
        rf, upload_id, content[:20], 10, 20
    )
    part_1.META["HTTP_CONTENT_RANGE"] = f"bytes 0-9/20"
    part_2.META["HTTP_CONTENT_RANGE"] = f"bytes 10-19/30"
    widget.handle_ajax(part_1)
    assert isinstance(widget.handle_ajax(part_2), HttpResponseBadRequest)
コード例 #2
0
def test_upload_validator_using_wrong_extension(rf: RequestFactory):
    widget = AjaxUploadWidget(
        ajax_target_path="/ajax",
        upload_validators=[
            ExtensionValidator(allowed_extensions=(".allowed-extension",))
        ],
    )
    widget.timeout = timedelta(seconds=1)
    content = load_test_data()

    upload_id = generate_new_upload_id(
        test_upload_validator_using_wrong_extension, content
    )

    request = create_upload_file_request(
        rf, content=b"should error", filename="test.wrong_extension"
    )
    response = widget.handle_ajax(request)
    assert response.status_code == 403

    request = create_upload_file_request(
        rf, content=b"should error", filename="test.allowed-extension"
    )
    response = widget.handle_ajax(request)
    assert response.status_code == 200
コード例 #3
0
def test_read_permission(client):
    u1, u2 = UserFactory(), UserFactory()
    filename = "test.bin"
    content = load_test_data()

    created_file = get_view_for_user(
        client=client,
        method=client.post,
        user=u1,
        url=reverse("api:staged-file-list"),
        data={filename: BytesIO(content)},
        format="multipart",
    )

    assert created_file.status_code == 201

    # Users should be able to see their own files
    response = get_view_for_user(
        client=client,
        user=u1,
        url=reverse("api:staged-file-list"),
        content_type="application/json",
    )
    assert response.status_code == 200
    assert response.json()["count"] == 1

    # Other users should not be able to see other files
    response = get_view_for_user(
        client=client,
        user=u2,
        url=reverse("api:staged-file-list"),
        content_type="application/json",
    )
    assert response.status_code == 200
    assert response.json()["count"] == 0
コード例 #4
0
def test_rfc7233_implementation_api(client):
    content = load_test_data()
    upload_id = generate_new_upload_id(
        test_rfc7233_implementation_api, content
    )
    url = reverse("api:staged-file-list")
    _, token = AuthToken.objects.create(user=UserFactory())

    part_1_response = create_partial_upload_file_request(
        client,
        upload_id,
        content,
        0,
        10,
        url=url,
        extra_headers={"HTTP_AUTHORIZATION": f"Bearer {token}"},
    )
    assert part_1_response.status_code == 201

    part_2_response = create_partial_upload_file_request(
        client,
        upload_id,
        content,
        10,
        len(content) // 2,
        url=url,
        extra_headers={"HTTP_AUTHORIZATION": f"Bearer {token}"},
    )
    assert part_2_response.status_code == 201

    part_3_response = create_partial_upload_file_request(
        client,
        upload_id,
        content,
        len(content) // 2,
        len(content),
        url=url,
        extra_headers={"HTTP_AUTHORIZATION": f"Bearer {token}"},
    )
    assert part_3_response.status_code == 201

    parsed_json = part_3_response.json()
    staged_file = StagedAjaxFile(uuid.UUID(parsed_json[0]["uuid"]))

    with staged_file.open() as f:
        staged_content = f.read()

    assert len(staged_content) == len(content)
    assert hash(staged_content) == hash(content)
    assert staged_content == content
コード例 #5
0
def test_wrong_upload_headers_rfc7233(rf: RequestFactory):
    widget = AjaxUploadWidget(ajax_target_path="/ajax")
    widget.timeout = timedelta(seconds=1)
    content = load_test_data()
    upload_id = generate_new_upload_id(
        test_wrong_upload_headers_rfc7233, content
    )
    post_request = create_partial_upload_file_request(
        rf, upload_id, content, 0, 10
    )
    assert isinstance(widget.handle_ajax(post_request), JsonResponse)
    post_request = create_partial_upload_file_request(
        rf, upload_id, content, 0, 10
    )
    post_request.META["X-Upload-ID"] = None
    post_request = force_post_update(post_request, "X-Upload-ID", None)
    assert isinstance(widget.handle_ajax(post_request), HttpResponseBadRequest)
    post_request = create_partial_upload_file_request(
        rf, upload_id, content, 0, 10
    )
    post_request.META[
        "HTTP_CONTENT_RANGE"
    ] = "corrupted data: 54343-3223/21323"
    assert isinstance(widget.handle_ajax(post_request), HttpResponseBadRequest)
    post_request = create_partial_upload_file_request(
        rf, upload_id, content, 0, 10
    )
    post_request.META["HTTP_CONTENT_RANGE"] = "bytes 54343-3223/21323"
    assert isinstance(widget.handle_ajax(post_request), HttpResponseBadRequest)
    post_request = create_partial_upload_file_request(
        rf, upload_id, content, 0, 10
    )
    post_request.META["HTTP_CONTENT_RANGE"] = "bytes 54343-3223/*"
    assert isinstance(widget.handle_ajax(post_request), HttpResponseBadRequest)
    post_request = create_partial_upload_file_request(
        rf, upload_id, content, 0, 10
    )
    post_request.META["HTTP_CONTENT_RANGE"] = "bytes 1000-3000/2000"
    assert isinstance(widget.handle_ajax(post_request), HttpResponseBadRequest)
    post_request = create_partial_upload_file_request(
        rf, upload_id, content, 0, 10
    )
    post_request.META["HTTP_CONTENT_RANGE"] = "bytes 1000-2000/*"
    assert isinstance(widget.handle_ajax(post_request), HttpResponseBadRequest)
    post_request = create_partial_upload_file_request(
        rf, upload_id, content, 0, 10
    )
    post_request.META["X-Upload-ID"] = "a" * 1000
    post_request = force_post_update(post_request, "X-Upload-ID", "a" * 1000)
    assert isinstance(widget.handle_ajax(post_request), HttpResponseBadRequest)
コード例 #6
0
def test_single_chunk_client_api(client):
    filename = "test.bin"
    content = load_test_data()
    token = Token.objects.create(user=UserFactory())

    response = client.post(
        path=reverse("api:staged-file-list"),
        data={filename: BytesIO(content)},
        format="multipart",
        HTTP_AUTHORIZATION=f"Token {token}",
    )

    assert response.status_code == 201

    parsed_json = response.json()

    assert len(parsed_json) == 1
    assert parsed_json[0]["filename"] == filename
    assert "uuid" in parsed_json[0]
    assert "extra_attrs" in parsed_json[0]
    staged_file = StagedAjaxFile(uuid.UUID(parsed_json[0]["uuid"]))
    with staged_file.open() as f:
        staged_content = f.read()
    assert staged_content == load_test_data()
コード例 #7
0
def test_single_chunk(rf: RequestFactory):
    widget = AjaxUploadWidget(ajax_target_path="/ajax")
    widget.timeout = timedelta(seconds=1)
    filename = "test.bin"
    post_request = create_upload_file_request(rf, filename=filename)
    response = widget.handle_ajax(post_request)
    assert isinstance(response, JsonResponse)
    parsed_json = json.loads(response.content)
    assert len(parsed_json) == 1
    assert parsed_json[0]["filename"] == filename
    assert "uuid" in parsed_json[0]
    assert "extra_attrs" in parsed_json[0]
    staged_file = StagedAjaxFile(uuid.UUID(parsed_json[0]["uuid"]))
    with staged_file.open() as f:
        staged_content = f.read()
    assert staged_content == load_test_data()
コード例 #8
0
def test_single_chunk(rf: RequestFactory):
    widget = AjaxUploadWidget(ajax_target_path="/ajax")
    widget.timeout = timedelta(seconds=1)
    filename = 'test.bin'
    post_request = create_upload_file_request(rf, filename=filename)
    response = widget.handle_ajax(post_request)
    assert isinstance(response, JsonResponse)
    parsed_json = json.loads(response.content)
    assert len(parsed_json) == 1
    assert parsed_json[0]["filename"] == filename
    assert "uuid" in parsed_json[0]
    assert "extra_attrs" in parsed_json[0]
    staged_file = StagedAjaxFile(uuid.UUID(parsed_json[0]["uuid"]))
    with staged_file.open() as f:
        staged_content = f.read()
    assert staged_content == load_test_data()
コード例 #9
0
def test_create_permission(client):
    filename = "test.bin"
    content = load_test_data()

    tests = ((UserFactory(), 201), (None, 401))

    for test in tests:
        response = get_view_for_user(
            client=client,
            method=client.post,
            user=test[0],
            url=reverse("api:staged-file-list"),
            data={filename: BytesIO(content)},
            format="multipart",
        )

        assert response.status_code == test[1]
コード例 #10
0
def test_rfc7233_implementation_client_api(client):
    content = load_test_data()
    upload_id = generate_new_upload_id(test_rfc7233_implementation_client_api,
                                       content)
    token = Token.objects.create(user=UserFactory())
    filename = "whatever.bin"

    start_byte = 0
    content_io = BytesIO(content)
    max_chunk_length = 2**15

    assert len(content) > 3 * max_chunk_length

    while True:
        chunk = content_io.read(max_chunk_length)
        if not chunk:
            break

        end_byte = start_byte + len(chunk)

        response = client.post(
            path=reverse("api:staged-file-list"),
            data={
                filename: BytesIO(chunk),
                "X-Upload-ID": upload_id
            },
            format="multipart",
            HTTP_CONTENT_RANGE=
            f"bytes {start_byte}-{end_byte - 1}/{len(content)}",
            HTTP_AUTHORIZATION=f"Token {token}",
        )
        assert response.status_code == 201

        start_byte += len(chunk)

    parsed_json = response.json()
    staged_file = StagedAjaxFile(uuid.UUID(parsed_json[0]["uuid"]))

    with staged_file.open() as f:
        staged_content = f.read()

    assert len(staged_content) == len(content)
    assert hash(staged_content) == hash(content)
    assert staged_content == content
コード例 #11
0
def test_wrong_upload_headers_rfc7233(rf: RequestFactory):
    widget = AjaxUploadWidget(ajax_target_path="/ajax")
    widget.timeout = timedelta(seconds=1)
    content = load_test_data()
    upload_id = generate_new_upload_id(test_wrong_upload_headers_rfc7233,
                                       content)
    post_request = create_partial_upload_file_request(rf, upload_id, content,
                                                      0, 10)
    assert isinstance(widget.handle_ajax(post_request), JsonResponse)
    post_request = create_partial_upload_file_request(rf, upload_id, content,
                                                      0, 10)
    post_request.META["X-Upload-ID"] = None
    post_request = force_post_update(post_request, "X-Upload-ID", None)
    assert isinstance(widget.handle_ajax(post_request), HttpResponseBadRequest)
    post_request = create_partial_upload_file_request(rf, upload_id, content,
                                                      0, 10)
    post_request.META[
        "HTTP_CONTENT_RANGE"] = "corrupted data: 54343-3223/21323"
    assert isinstance(widget.handle_ajax(post_request), HttpResponseBadRequest)
    post_request = create_partial_upload_file_request(rf, upload_id, content,
                                                      0, 10)
    post_request.META["HTTP_CONTENT_RANGE"] = "bytes 54343-3223/21323"
    assert isinstance(widget.handle_ajax(post_request), HttpResponseBadRequest)
    post_request = create_partial_upload_file_request(rf, upload_id, content,
                                                      0, 10)
    post_request.META["HTTP_CONTENT_RANGE"] = "bytes 54343-3223/*"
    assert isinstance(widget.handle_ajax(post_request), HttpResponseBadRequest)
    post_request = create_partial_upload_file_request(rf, upload_id, content,
                                                      0, 10)
    post_request.META["HTTP_CONTENT_RANGE"] = "bytes 1000-3000/2000"
    assert isinstance(widget.handle_ajax(post_request), HttpResponseBadRequest)
    post_request = create_partial_upload_file_request(rf, upload_id, content,
                                                      0, 10)
    post_request.META["HTTP_CONTENT_RANGE"] = "bytes 1000-2000/*"
    assert isinstance(widget.handle_ajax(post_request), HttpResponseBadRequest)
    post_request = create_partial_upload_file_request(rf, upload_id, content,
                                                      0, 10)
    post_request.META["X-Upload-ID"] = "a" * 1000
    post_request = force_post_update(post_request, "X-Upload-ID", "a" * 1000)
    assert isinstance(widget.handle_ajax(post_request), HttpResponseBadRequest)
コード例 #12
0
def test_single_chunk_api(client):
    filename = "test.bin"
    token = Token.objects.create(user=UserFactory())

    response = create_upload_file_request(
        rf=client,
        filename=filename,
        url=reverse("api:staged-file-list"),
        extra_headers={"HTTP_AUTHORIZATION": f"Token {token}"},
    )

    assert response.status_code == 201

    parsed_json = response.json()

    assert parsed_json[0]["filename"] == filename
    assert "uuid" in parsed_json[0]
    assert "extra_attrs" in parsed_json[0]
    staged_file = StagedAjaxFile(uuid.UUID(parsed_json[0]["uuid"]))
    with staged_file.open() as f:
        staged_content = f.read()
    assert staged_content == load_test_data()
コード例 #13
0
def test_rfc7233_implementation(rf: RequestFactory):
    content = load_test_data()
    upload_id = generate_new_upload_id(test_rfc7233_implementation, content)
    part_1 = create_partial_upload_file_request(rf, upload_id, content, 0, 10)
    part_2 = create_partial_upload_file_request(rf, upload_id, content, 10,
                                                len(content) // 2)
    part_3 = create_partial_upload_file_request(rf, upload_id, content,
                                                len(content) // 2,
                                                len(content))
    widget = AjaxUploadWidget(ajax_target_path="/ajax")
    widget.timeout = timedelta(seconds=1)
    response = widget.handle_ajax(part_1)
    assert isinstance(response, JsonResponse)
    response = widget.handle_ajax(part_2)
    assert isinstance(response, JsonResponse)
    response = widget.handle_ajax(part_3)
    assert isinstance(response, JsonResponse)
    parsed_json = json.loads(response.content)
    staged_file = StagedAjaxFile(uuid.UUID(parsed_json[0]["uuid"]))
    with staged_file.open() as f:
        staged_content = f.read()
    assert staged_content == content
コード例 #14
0
def test_rfc7233_implementation(rf: RequestFactory):
    content = load_test_data()
    upload_id = generate_new_upload_id(test_rfc7233_implementation, content)
    part_1 = create_partial_upload_file_request(rf, upload_id, content, 0, 10)
    part_2 = create_partial_upload_file_request(
        rf, upload_id, content, 10, len(content) // 2
    )
    part_3 = create_partial_upload_file_request(
        rf, upload_id, content, len(content) // 2, len(content)
    )
    widget = AjaxUploadWidget(ajax_target_path="/ajax")
    widget.timeout = timedelta(seconds=1)
    response = widget.handle_ajax(part_1)
    assert isinstance(response, JsonResponse)
    response = widget.handle_ajax(part_2)
    assert isinstance(response, JsonResponse)
    response = widget.handle_ajax(part_3)
    assert isinstance(response, JsonResponse)
    parsed_json = json.loads(response.content)
    staged_file = StagedAjaxFile(uuid.UUID(parsed_json[0]["uuid"]))
    with staged_file.open() as f:
        staged_content = f.read()
    assert staged_content == content
コード例 #15
0
def test_inconsistent_chunks_rfc7233(rf: RequestFactory):
    widget = AjaxUploadWidget(ajax_target_path="/ajax")
    widget.timeout = timedelta(seconds=1)
    content = load_test_data()
    # Overlapping chunks
    upload_id = generate_new_upload_id(test_inconsistent_chunks_rfc7233,
                                       content)
    part_1 = create_partial_upload_file_request(rf, upload_id, content, 0, 10)
    part_2 = create_partial_upload_file_request(rf, upload_id, content, 5, 15)
    widget.handle_ajax(part_1)
    assert isinstance(widget.handle_ajax(part_2), HttpResponseBadRequest)
    # Inconsistent filenames
    upload_id += "x"
    part_1 = create_partial_upload_file_request(rf,
                                                upload_id,
                                                content,
                                                0,
                                                10,
                                                filename="a")
    part_2 = create_partial_upload_file_request(rf,
                                                upload_id,
                                                content,
                                                10,
                                                20,
                                                filename="b")
    widget.handle_ajax(part_1)
    assert isinstance(widget.handle_ajax(part_2), HttpResponseBadRequest)
    # Inconsistent total size
    upload_id += "x"
    part_1 = create_partial_upload_file_request(rf, upload_id, content[:20], 0,
                                                10)
    part_2 = create_partial_upload_file_request(rf, upload_id, content[:20],
                                                10, 20)
    part_1.META["HTTP_CONTENT_RANGE"] = f"bytes 0-9/20"
    part_2.META["HTTP_CONTENT_RANGE"] = f"bytes 10-19/30"
    widget.handle_ajax(part_1)
    assert isinstance(widget.handle_ajax(part_2), HttpResponseBadRequest)
コード例 #16
0
def test_upload_validator_using_wrong_extension(rf: RequestFactory):
    widget = AjaxUploadWidget(
        ajax_target_path="/ajax",
        upload_validators=[
            ExtensionValidator(allowed_extensions=('.allowed-extension', ))
        ],
    )
    widget.timeout = timedelta(seconds=1)
    content = load_test_data()

    upload_id = generate_new_upload_id(
        test_upload_validator_using_wrong_extension, content)

    request = create_upload_file_request(rf,
                                         content=b"should error",
                                         filename="test.wrong_extension")
    response = widget.handle_ajax(request)
    assert response.status_code == 403

    request = create_upload_file_request(rf,
                                         content=b"should error",
                                         filename="test.allowed-extension")
    response = widget.handle_ajax(request)
    assert response.status_code == 200
コード例 #17
0
def test_wrong_upload_headers_rfc7233_api(client):
    content = load_test_data()
    upload_id = generate_new_upload_id(test_wrong_upload_headers_rfc7233_api,
                                       content)
    url = reverse("api:staged-file-list")
    token = Token.objects.create(user=UserFactory())

    response = create_partial_upload_file_request(
        client,
        upload_id,
        content,
        0,
        10,
        url=url,
        extra_headers={"HTTP_AUTHORIZATION": f"Token {token}"},
    )
    assert response.status_code == 201

    response = create_partial_upload_file_request(
        client,
        None,
        content,
        0,
        10,
        url=url,
        extra_headers={"HTTP_AUTHORIZATION": f"Token {token}"},
    )
    assert response.status_code == 400

    response = create_partial_upload_file_request(
        client,
        upload_id,
        content,
        0,
        10,
        url=url,
        http_content_range="corrupted data: 54343-3223/21323",
        extra_headers={"HTTP_AUTHORIZATION": f"Token {token}"},
    )
    assert response.status_code == 400

    response = create_partial_upload_file_request(
        client,
        upload_id,
        content,
        0,
        10,
        url=url,
        http_content_range="bytes 54343-3223/21323",
        extra_headers={"HTTP_AUTHORIZATION": f"Token {token}"},
    )
    assert response.status_code == 400

    response = create_partial_upload_file_request(
        client,
        upload_id,
        content,
        0,
        10,
        url=url,
        http_content_range="bytes 54343-3223/*",
        extra_headers={"HTTP_AUTHORIZATION": f"Token {token}"},
    )
    assert response.status_code == 400

    response = create_partial_upload_file_request(
        client,
        upload_id,
        content,
        0,
        10,
        url=url,
        http_content_range="bytes 1000-3000/2000",
        extra_headers={"HTTP_AUTHORIZATION": f"Token {token}"},
    )
    assert response.status_code == 400

    response = create_partial_upload_file_request(
        client,
        upload_id,
        content,
        0,
        10,
        url=url,
        http_content_range="bytes 1000-2000/*",
        extra_headers={"HTTP_AUTHORIZATION": f"Token {token}"},
    )
    assert response.status_code == 400

    response = create_partial_upload_file_request(
        client,
        "a" * 1000,
        content,
        0,
        10,
        url=url,
        extra_headers={"HTTP_AUTHORIZATION": f"Token {token}"},
    )
    assert response.status_code == 400
コード例 #18
0
def test_inconsistent_chunks_rfc7233(client):
    content = load_test_data()
    url = reverse("api:staged-file-list")
    token = Token.objects.create(user=UserFactory())

    # Overlapping chunks
    upload_id = generate_new_upload_id(test_inconsistent_chunks_rfc7233,
                                       content)
    part_1 = create_partial_upload_file_request(
        client,
        upload_id,
        content,
        0,
        10,
        url=url,
        extra_headers={"HTTP_AUTHORIZATION": f"Token {token}"},
    )
    assert part_1.status_code == 201
    part_2 = create_partial_upload_file_request(
        client,
        upload_id,
        content,
        5,
        15,
        url=url,
        extra_headers={"HTTP_AUTHORIZATION": f"Token {token}"},
    )
    assert part_2.status_code == 400

    # Inconsistent filenames
    upload_id += "x"
    part_1 = create_partial_upload_file_request(
        client,
        upload_id,
        content,
        0,
        10,
        filename="a",
        url=url,
        extra_headers={"HTTP_AUTHORIZATION": f"Token {token}"},
    )
    assert part_1.status_code == 201
    part_2 = create_partial_upload_file_request(
        client,
        upload_id,
        content,
        10,
        20,
        filename="b",
        url=url,
        extra_headers={"HTTP_AUTHORIZATION": f"Token {token}"},
    )
    assert part_2.status_code == 400

    # Inconsistent total size
    upload_id += "x"
    part_1 = create_partial_upload_file_request(
        client,
        upload_id,
        content[:20],
        0,
        10,
        url=url,
        http_content_range="bytes 0-9/20",
        extra_headers={"HTTP_AUTHORIZATION": f"Token {token}"},
    )
    assert part_1.status_code == 201
    part_2 = create_partial_upload_file_request(
        client,
        upload_id,
        content[:20],
        10,
        20,
        url=url,
        http_content_range="bytes 10-19/30",
        extra_headers={"HTTP_AUTHORIZATION": f"Token {token}"},
    )
    assert part_2.status_code == 400