feat: B2 uit voor veilige archive-downloads
This commit is contained in:
@@ -411,6 +411,14 @@ class FileOpsService:
|
||||
history_mode = self._download_mode_from_resolved_targets(resolved_targets)
|
||||
history_path = self._summarize_download_targets([target.relative for target in resolved_targets])
|
||||
history_download_name = self._download_name_for_targets(resolved_targets)
|
||||
|
||||
if history_mode != "single_file":
|
||||
raise AppError(
|
||||
code="invalid_request",
|
||||
message="Archive downloads must be prepared first",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
history_entry_id = self._record_download_status(
|
||||
status="requested",
|
||||
mode=history_mode,
|
||||
@@ -418,10 +426,7 @@ class FileOpsService:
|
||||
download_name=history_download_name,
|
||||
)
|
||||
|
||||
if len(resolved_targets) == 1 and resolved_targets[0].absolute.is_file():
|
||||
prepared = self._prepare_single_file_download(resolved_targets[0])
|
||||
else:
|
||||
prepared = self._prepare_zip_download(resolved_targets, history_download_name)
|
||||
prepared = self._prepare_single_file_download(resolved_targets[0])
|
||||
|
||||
self._record_download_status(
|
||||
status="ready",
|
||||
@@ -757,16 +762,7 @@ class FileOpsService:
|
||||
}
|
||||
|
||||
def _prepare_zip_download(self, resolved_targets: list, download_name: str) -> dict:
|
||||
archive_names: set[str] = set()
|
||||
for resolved_target in resolved_targets:
|
||||
archive_name = resolved_target.absolute.name
|
||||
if archive_name in archive_names:
|
||||
raise AppError(
|
||||
code="invalid_request",
|
||||
message="Selected items must have distinct top-level names",
|
||||
status_code=400,
|
||||
)
|
||||
archive_names.add(archive_name)
|
||||
self._validate_zip_download_archive_names(resolved_targets)
|
||||
self._run_zip_download_preflight(resolved_targets)
|
||||
|
||||
buffer = BytesIO()
|
||||
@@ -786,6 +782,18 @@ class FileOpsService:
|
||||
"content_type": "application/zip",
|
||||
}
|
||||
|
||||
def _validate_zip_download_archive_names(self, resolved_targets: list) -> None:
|
||||
archive_names: set[str] = set()
|
||||
for resolved_target in resolved_targets:
|
||||
archive_name = resolved_target.absolute.name
|
||||
if archive_name in archive_names:
|
||||
raise AppError(
|
||||
code="invalid_request",
|
||||
message="Selected items must have distinct top-level names",
|
||||
status_code=400,
|
||||
)
|
||||
archive_names.add(archive_name)
|
||||
|
||||
def _download_name_for_targets(self, resolved_targets: list) -> str:
|
||||
if len(resolved_targets) == 1 and resolved_targets[0].absolute.is_file():
|
||||
return resolved_targets[0].absolute.name
|
||||
|
||||
Reference in New Issue
Block a user