102 lines
3.3 KiB
Python
102 lines
3.3 KiB
Python
from __future__ import annotations
|
|
|
|
import io
|
|
import hashlib
|
|
import unittest
|
|
import zipfile
|
|
from types import SimpleNamespace
|
|
from unittest.mock import patch
|
|
|
|
from fastapi import UploadFile
|
|
|
|
from govoplan_files.backend.routes.uploads import (
|
|
_validate_archive_preview_token,
|
|
preview_archive_upload,
|
|
)
|
|
from govoplan_files.backend.storage.common import FileStorageError
|
|
|
|
|
|
def _archive_bytes() -> bytes:
|
|
target = io.BytesIO()
|
|
with zipfile.ZipFile(target, "w", compression=zipfile.ZIP_DEFLATED) as archive:
|
|
archive.writestr("folder/report.txt", b"report")
|
|
return target.getvalue()
|
|
|
|
|
|
class ArchivePreviewTokenTests(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
self.settings = SimpleNamespace(
|
|
file_upload_zip_max_bytes=10 * 1024 * 1024,
|
|
file_archive_max_entries=10_000,
|
|
file_archive_max_expanded_bytes=2 * 1024 * 1024 * 1024,
|
|
file_archive_max_expansion_ratio=100,
|
|
file_archive_preview_ttl_seconds=30 * 60,
|
|
)
|
|
self.principal = SimpleNamespace(
|
|
tenant_id="tenant-1",
|
|
user=SimpleNamespace(id="user-1"),
|
|
)
|
|
|
|
def test_preview_token_is_bound_to_actor_archive_and_destination(self) -> None:
|
|
archive_data = _archive_bytes()
|
|
upload = UploadFile(
|
|
file=io.BytesIO(archive_data),
|
|
filename="monthly.zip",
|
|
)
|
|
with patch(
|
|
"govoplan_files.backend.routes.uploads.settings",
|
|
self.settings,
|
|
):
|
|
preview = preview_archive_upload(
|
|
file=upload,
|
|
owner_type="user",
|
|
owner_id="user-1",
|
|
path="incoming",
|
|
campaign_id=None,
|
|
password=None,
|
|
principal=self.principal,
|
|
)
|
|
_validate_archive_preview_token(
|
|
preview.preview_token,
|
|
tenant_id="tenant-1",
|
|
user_id="user-1",
|
|
owner_type="user",
|
|
owner_id="user-1",
|
|
path="incoming",
|
|
campaign_id=None,
|
|
archive_format="zip",
|
|
archive_sha256=hashlib.sha256(archive_data).hexdigest(),
|
|
)
|
|
with self.assertRaisesRegex(
|
|
FileStorageError, "does not match this upload destination"
|
|
):
|
|
_validate_archive_preview_token(
|
|
preview.preview_token,
|
|
tenant_id="tenant-1",
|
|
user_id="user-1",
|
|
owner_type="user",
|
|
owner_id="user-1",
|
|
path="elsewhere",
|
|
campaign_id=None,
|
|
archive_format="zip",
|
|
archive_sha256=hashlib.sha256(archive_data).hexdigest(),
|
|
)
|
|
with self.assertRaisesRegex(
|
|
FileStorageError, "contents changed"
|
|
):
|
|
_validate_archive_preview_token(
|
|
preview.preview_token,
|
|
tenant_id="tenant-1",
|
|
user_id="user-1",
|
|
owner_type="user",
|
|
owner_id="user-1",
|
|
path="incoming",
|
|
campaign_id=None,
|
|
archive_format="zip",
|
|
archive_sha256="0" * 64,
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|