fix(webdav): enforce storage quota on WebDAV PUT uploads

Adds storage quota checking to the WebDAV PUT handler, which was missing
while present in other upload handlers (regular upload and chunked upload).

The quota check happens after the file is spooled to a temp file (so we
know the exact size) but before it's moved to permanent storage. If the
quota is exceeded, the temp file is cleaned up and a 507 Insufficient
Storage error is returned.

Fixes #104
This commit is contained in:
BillionClaw
2026-03-17 16:04:20 +08:00
parent 5279e0c266
commit ec09136836
@@ -23,6 +23,7 @@ use crate::application::dtos::folder_dto::FolderDto;
use crate::application::ports::file_ports::FileRetrievalUseCase;
use crate::application::ports::file_ports::{FileManagementUseCase, FileUploadUseCase};
use crate::application::ports::inbound::FolderUseCase;
use crate::application::ports::storage_ports::StorageUsagePort;
use crate::application::services::file_retrieval_service::FileRetrievalService;
use crate::application::services::folder_service::FolderService;
use crate::common::di::AppState;
@@ -920,6 +921,27 @@ async fn handle_put(
let hash = hasher.finalize().to_hex().to_string();
// ── Quota enforcement ────────────────────────────────────
if let Some(storage_svc) = state.storage_usage_service.as_ref() {
if let Err(err) = storage_svc
.check_storage_quota(user.id, total_bytes as u64)
.await
{
let _ = tokio::fs::remove_file(&temp_path).await;
tracing::warn!(
"⛔ WEBDAV PUT REJECTED (quota): user={}, file={}, size={}",
user.id,
path,
total_bytes
);
return Err(AppError::new(
StatusCode::INSUFFICIENT_STORAGE,
err.message,
"QuotaExceeded",
));
}
}
// ── Atomic store: temp file → dedup blob + DB metadata update ──
let result = file_upload_service
.update_file_streaming(