refactor(server): file_management_service: move all method without owner check into private, add folder_ports
This commit is contained in:
@@ -117,10 +117,10 @@ impl FileHandler {
|
||||
|
||||
// ── SECURITY: Verify folder ownership before upload (IDOR V-03 fix) ──
|
||||
if let Some(ref fid) = folder_id {
|
||||
use crate::application::ports::inbound::FolderUseCase;
|
||||
use crate::application::ports::folder_ports::FolderUseCase;
|
||||
let folder_service = &state.applications.folder_service;
|
||||
if folder_service
|
||||
.get_folder_owned(fid, auth_user.id)
|
||||
.get_folder_with_perms(fid, auth_user.id)
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
@@ -875,7 +875,7 @@ impl FileHandler {
|
||||
|
||||
// Auth required: trash-first with dedup cleanup + ownership verification
|
||||
let result = mgmt
|
||||
.delete_with_cleanup(&id, auth_user.id)
|
||||
.delete_and_cleanup_with_perms(&id, auth_user.id)
|
||||
.await
|
||||
.map(|was_trashed| {
|
||||
if was_trashed {
|
||||
@@ -917,7 +917,10 @@ impl FileHandler {
|
||||
|
||||
tracing::info!("Renaming file {} to \"{}\"", id, new_name);
|
||||
let mgmt = &state.applications.file_management_service;
|
||||
match mgmt.rename_file_owned(&id, auth_user.id, &new_name).await {
|
||||
match mgmt
|
||||
.rename_file_with_perms(&id, auth_user.id, &new_name)
|
||||
.await
|
||||
{
|
||||
Ok(file_dto) => (StatusCode::OK, Json(file_dto)).into_response(),
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
@@ -935,7 +938,7 @@ impl FileHandler {
|
||||
let mgmt = &state.applications.file_management_service;
|
||||
|
||||
match mgmt
|
||||
.move_file_owned(&id, auth_user.id, payload.folder_id)
|
||||
.move_file_with_perms(&id, auth_user.id, payload.folder_id)
|
||||
.await
|
||||
{
|
||||
Ok(file) => (StatusCode::OK, Json(file)).into_response(),
|
||||
@@ -956,7 +959,10 @@ impl FileHandler {
|
||||
.map(|s| s.to_string());
|
||||
|
||||
let mgmt = &state.applications.file_management_service;
|
||||
match mgmt.move_file_owned(&id, auth_user.id, folder_id).await {
|
||||
match mgmt
|
||||
.move_file_with_perms(&id, auth_user.id, folder_id)
|
||||
.await
|
||||
{
|
||||
Ok(file_dto) => (StatusCode::OK, Json(file_dto)).into_response(),
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ use crate::application::dtos::folder_dto::{
|
||||
use crate::application::dtos::folder_listing_dto::FolderListingDto;
|
||||
use crate::application::dtos::pagination::PaginationRequestDto;
|
||||
use crate::application::ports::file_ports::FileRetrievalUseCase;
|
||||
use crate::application::ports::inbound::FolderUseCase;
|
||||
use crate::application::ports::folder_ports::FolderUseCase;
|
||||
use crate::application::ports::trash_ports::TrashUseCase;
|
||||
use crate::application::services::folder_service::FolderService;
|
||||
use crate::common::di::AppState as GlobalAppState;
|
||||
@@ -76,7 +76,7 @@ impl FolderHandler {
|
||||
}
|
||||
}
|
||||
|
||||
match service.create_folder(dto, auth_user.id).await {
|
||||
match service.create_folder_with_perms(dto, auth_user.id).await {
|
||||
Ok(folder) => (StatusCode::CREATED, Json(folder)).into_response(),
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
@@ -244,7 +244,10 @@ impl FolderHandler {
|
||||
Path(id): Path<String>,
|
||||
Json(dto): Json<RenameFolderDto>,
|
||||
) -> impl IntoResponse {
|
||||
match service.rename_folder(&id, dto, auth_user.id).await {
|
||||
match service
|
||||
.rename_folder_with_perms(&id, dto, auth_user.id)
|
||||
.await
|
||||
{
|
||||
Ok(folder) => (StatusCode::OK, Json(folder)).into_response(),
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
@@ -257,7 +260,7 @@ impl FolderHandler {
|
||||
Path(id): Path<String>,
|
||||
Json(dto): Json<MoveFolderDto>,
|
||||
) -> impl IntoResponse {
|
||||
match service.move_folder(&id, dto, auth_user.id).await {
|
||||
match service.move_folder_with_perms(&id, dto, auth_user.id).await {
|
||||
Ok(folder) => (StatusCode::OK, Json(folder)).into_response(),
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
@@ -269,7 +272,7 @@ impl FolderHandler {
|
||||
auth_user: AuthUser,
|
||||
Path(id): Path<String>,
|
||||
) -> impl IntoResponse {
|
||||
match service.delete_folder(&id, auth_user.id).await {
|
||||
match service.delete_folder_with_perms(&id, auth_user.id).await {
|
||||
Ok(_) => StatusCode::NO_CONTENT.into_response(),
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
@@ -304,7 +307,7 @@ impl FolderHandler {
|
||||
|
||||
// Fallback to permanent delete if trash is unavailable or failed
|
||||
let folder_service = &state.applications.folder_service;
|
||||
match folder_service.delete_folder(&id, user_id).await {
|
||||
match folder_service.delete_folder_with_perms(&id, user_id).await {
|
||||
Ok(_) => {
|
||||
tracing::info!("Folder permanently deleted: {}", id);
|
||||
StatusCode::NO_CONTENT.into_response()
|
||||
|
||||
@@ -22,7 +22,7 @@ use crate::application::dtos::file_dto::FileDto;
|
||||
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::folder_ports::FolderUseCase;
|
||||
use crate::application::ports::storage_ports::StorageUsagePort;
|
||||
use crate::application::services::file_retrieval_service::FileRetrievalService;
|
||||
use crate::application::services::folder_service::FolderService;
|
||||
@@ -1046,7 +1046,7 @@ async fn handle_mkcol(
|
||||
// their proper HTTP status codes (was: blanket 500 swallowed
|
||||
// ownership-rejection NotFound from verify_owner).
|
||||
let created = folder_service
|
||||
.create_folder(create_dto, user.id)
|
||||
.create_folder_with_perms(create_dto, user.id)
|
||||
.await
|
||||
.map_err(AppError::from)?;
|
||||
parent_id = Some(created.id);
|
||||
@@ -1092,7 +1092,7 @@ async fn handle_delete(
|
||||
match resolver.resolve_path_for_user(&path, user.id).await {
|
||||
Ok(ResolvedResource::Folder(folder)) => {
|
||||
folder_service
|
||||
.delete_folder(&folder.id, user.id)
|
||||
.delete_folder_with_perms(&folder.id, user.id)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
AppError::internal_error(format!("Failed to delete folder: {}", e))
|
||||
@@ -1100,7 +1100,7 @@ async fn handle_delete(
|
||||
}
|
||||
Ok(ResolvedResource::File(file)) => {
|
||||
file_management_service
|
||||
.delete_file(&file.id)
|
||||
.delete_file_with_perms(&file.id, user.id)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
AppError::internal_error(format!("Failed to delete file: {}", e))
|
||||
@@ -1115,7 +1115,7 @@ async fn handle_delete(
|
||||
if let Ok(folder) = folder_result {
|
||||
assert_owner(folder.owner_id.as_deref(), &user.id.to_string(), &path)?;
|
||||
folder_service
|
||||
.delete_folder(&folder.id, user.id)
|
||||
.delete_folder_with_perms(&folder.id, user.id)
|
||||
.await
|
||||
.map_err(|e| AppError::internal_error(format!("Failed to delete folder: {}", e)))?;
|
||||
} else {
|
||||
@@ -1126,7 +1126,7 @@ async fn handle_delete(
|
||||
assert_owner(file.owner_id.as_deref(), &user.id.to_string(), &path)?;
|
||||
|
||||
file_management_service
|
||||
.delete_file(&file.id)
|
||||
.delete_file_with_perms(&file.id, user.id)
|
||||
.await
|
||||
.map_err(|e| AppError::internal_error(format!("Failed to delete file: {}", e)))?;
|
||||
}
|
||||
@@ -1248,7 +1248,7 @@ async fn handle_move(
|
||||
};
|
||||
|
||||
folder_service
|
||||
.move_folder(&folder.id, move_dto, user.id)
|
||||
.move_folder_with_perms(&folder.id, move_dto, user.id)
|
||||
.await
|
||||
.map_err(AppError::from)?;
|
||||
|
||||
@@ -1257,7 +1257,7 @@ async fn handle_move(
|
||||
name: dest_folder_name.to_string(),
|
||||
};
|
||||
folder_service
|
||||
.rename_folder(&folder.id, rename_dto, user.id)
|
||||
.rename_folder_with_perms(&folder.id, rename_dto, user.id)
|
||||
.await
|
||||
.map_err(AppError::from)?;
|
||||
}
|
||||
@@ -1291,13 +1291,13 @@ async fn handle_move(
|
||||
)?;
|
||||
}
|
||||
file_management_service
|
||||
.move_file(&file.id, Some(dest_parent_path.to_string()))
|
||||
.move_file_with_perms(&file.id, user.id, Some(dest_parent_path.to_string()))
|
||||
.await
|
||||
.map_err(AppError::from)?;
|
||||
}
|
||||
if file.name != dest_filename {
|
||||
file_management_service
|
||||
.rename_file(&file.id, dest_filename)
|
||||
.rename_file_with_perms(&file.id, user.id, dest_filename)
|
||||
.await
|
||||
.map_err(AppError::from)?;
|
||||
}
|
||||
@@ -1349,7 +1349,7 @@ async fn handle_move(
|
||||
};
|
||||
|
||||
folder_service
|
||||
.move_folder(&folder.id, move_dto, user.id)
|
||||
.move_folder_with_perms(&folder.id, move_dto, user.id)
|
||||
.await
|
||||
.map_err(|e| AppError::internal_error(format!("Failed to move folder: {}", e)))?;
|
||||
|
||||
@@ -1358,7 +1358,7 @@ async fn handle_move(
|
||||
name: dest_folder_name.to_string(),
|
||||
};
|
||||
folder_service
|
||||
.rename_folder(&folder.id, rename_dto, user.id)
|
||||
.rename_folder_with_perms(&folder.id, rename_dto, user.id)
|
||||
.await
|
||||
.map_err(AppError::from)?;
|
||||
}
|
||||
@@ -1398,13 +1398,13 @@ async fn handle_move(
|
||||
)?;
|
||||
}
|
||||
file_management_service
|
||||
.move_file(&file.id, Some(dest_parent_path.to_string()))
|
||||
.move_file_with_perms(&file.id, user.id, Some(dest_parent_path.to_string()))
|
||||
.await
|
||||
.map_err(AppError::from)?;
|
||||
}
|
||||
if file.name != dest_filename {
|
||||
file_management_service
|
||||
.rename_file(&file.id, dest_filename)
|
||||
.rename_file_with_perms(&file.id, user.id, dest_filename)
|
||||
.await
|
||||
.map_err(AppError::from)?;
|
||||
}
|
||||
@@ -1535,8 +1535,9 @@ async fn handle_copy(
|
||||
if recursive {
|
||||
let file_management_service = &state.applications.file_management_service;
|
||||
file_management_service
|
||||
.copy_folder_tree(
|
||||
.copy_folder_tree_with_perms(
|
||||
&folder.id,
|
||||
user.id,
|
||||
target_parent_id,
|
||||
Some(dest_folder_name.to_string()),
|
||||
)
|
||||
@@ -1550,7 +1551,7 @@ async fn handle_copy(
|
||||
parent_id: target_parent_id,
|
||||
};
|
||||
folder_service
|
||||
.create_folder(create_dto, user.id)
|
||||
.create_folder_with_perms(create_dto, user.id)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
AppError::internal_error(format!(
|
||||
@@ -1586,7 +1587,7 @@ async fn handle_copy(
|
||||
|
||||
let file_management_service = &state.applications.file_management_service;
|
||||
file_management_service
|
||||
.copy_file(&file.id, target_folder_id)
|
||||
.copy_file_with_perms(&file.id, user.id, target_folder_id)
|
||||
.await
|
||||
.map_err(|e| AppError::internal_error(format!("Failed to copy file: {}", e)))?;
|
||||
}
|
||||
@@ -1639,8 +1640,9 @@ async fn handle_copy(
|
||||
if recursive {
|
||||
let file_management_service = &state.applications.file_management_service;
|
||||
file_management_service
|
||||
.copy_folder_tree(
|
||||
.copy_folder_tree_with_perms(
|
||||
&folder.id,
|
||||
user.id,
|
||||
target_parent_id,
|
||||
Some(dest_folder_name.to_string()),
|
||||
)
|
||||
@@ -1654,7 +1656,7 @@ async fn handle_copy(
|
||||
parent_id: target_parent_id,
|
||||
};
|
||||
folder_service
|
||||
.create_folder(create_dto, user.id)
|
||||
.create_folder_with_perms(create_dto, user.id)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
AppError::internal_error(format!(
|
||||
@@ -1697,7 +1699,7 @@ async fn handle_copy(
|
||||
|
||||
let file_management_service = &state.applications.file_management_service;
|
||||
file_management_service
|
||||
.copy_file(&file.id, target_folder_id)
|
||||
.copy_file_with_perms(&file.id, user.id, target_folder_id)
|
||||
.await
|
||||
.map_err(|e| AppError::internal_error(format!("Failed to copy file: {}", e)))?;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user