refactor(create_folder): add an ownership check while creating a folder + refactor code

This commit is contained in:
Edouard Vanbelle
2026-05-20 12:48:06 +02:00
parent 91ff3df35f
commit f8b30e78a6
9 changed files with 76 additions and 89 deletions
+1 -19
View File
@@ -76,25 +76,7 @@ impl FolderHandler {
}
}
// ── SECURITY: Verify parent folder ownership (IDOR V-04 fix) ──
if let Some(ref parent_id) = dto.parent_id {
use crate::application::ports::inbound::FolderUseCase;
if service
.get_folder_owned(parent_id, auth_user.id)
.await
.is_err()
{
tracing::warn!(
"create_folder: user '{}' attempted to create folder in parent '{}' owned by another user",
auth_user.username,
parent_id,
);
return AppError::not_found(format!("Parent folder not found: {}", parent_id))
.into_response();
}
}
match service.create_folder(dto).await {
match service.create_folder(dto, auth_user.id).await {
Ok(folder) => (StatusCode::CREATED, Json(folder)).into_response(),
Err(err) => AppError::from(err).into_response(),
}
@@ -999,6 +999,7 @@ async fn handle_mkcol(
req: Request<Body>,
path: String,
) -> Result<Response<Body>, AppError> {
let user = extract_user(&req)?;
let folder_service = &state.applications.folder_service;
if path.is_empty() || path == "/" {
@@ -1041,15 +1042,13 @@ async fn handle_mkcol(
name: segment.to_string(),
parent_id: parent_id.clone(),
};
// Propagate DomainError -> AppError so NotFound/Conflict map to
// their proper HTTP status codes (was: blanket 500 swallowed
// ownership-rejection NotFound from verify_owner).
let created = folder_service
.create_folder(create_dto)
.create_folder(create_dto, user.id)
.await
.map_err(|e| {
AppError::internal_error(format!(
"Failed to create folder '{}': {}",
accumulated_path, e
))
})?;
.map_err(AppError::from)?;
parent_id = Some(created.id);
}
}
@@ -1551,7 +1550,7 @@ async fn handle_copy(
parent_id: target_parent_id,
};
folder_service
.create_folder(create_dto)
.create_folder(create_dto, user.id)
.await
.map_err(|e| {
AppError::internal_error(format!(
@@ -1655,7 +1654,7 @@ async fn handle_copy(
parent_id: target_parent_id,
};
folder_service
.create_folder(create_dto)
.create_folder(create_dto, user.id)
.await
.map_err(|e| {
AppError::internal_error(format!(
+2 -1
View File
@@ -551,6 +551,7 @@ async fn handle_put(
.map_err(|e| AppError::internal_error(format!("Failed to update file: {}", e)))?;
// Update audio metadata for supported audio files.
// TODO: use notification service or hook
if let Some(ref audio_service) = state.applications.audio_metadata_service
&& let Ok(file_id) = uuid::Uuid::parse_str(&updated.id)
{
@@ -655,7 +656,7 @@ async fn handle_mkcol(
name: segment.to_string(),
parent_id: Some(parent_id.clone()),
};
match folder_service.create_folder(dto).await {
match folder_service.create_folder(dto, user.id).await {
Ok(created) => {
parent_id = created.id.clone();
}