style: apply rustfmt formatting to fix CI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -342,7 +342,9 @@ async fn logout(
|
||||
.ok()
|
||||
.map(|dto| dto.refresh_token)
|
||||
.or_else(|| cookie_auth::extract_cookie_value(&headers, cookie_auth::REFRESH_COOKIE))
|
||||
.ok_or_else(|| AppError::unauthorized("Refresh token required for logout (JSON body or cookie)"))?;
|
||||
.ok_or_else(|| {
|
||||
AppError::unauthorized("Refresh token required for logout (JSON body or cookie)")
|
||||
})?;
|
||||
|
||||
auth_service
|
||||
.auth_application_service
|
||||
|
||||
@@ -164,7 +164,10 @@ pub async fn move_files_batch(
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Batch move_files failed: {}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Batch operation failed".to_string())
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Batch operation failed".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
// Convert result to DTO
|
||||
@@ -217,7 +220,10 @@ pub async fn copy_files_batch(
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Batch copy_files failed: {}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Batch operation failed".to_string())
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Batch operation failed".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
// Convert result to DTO
|
||||
@@ -270,7 +276,10 @@ pub async fn delete_files_batch(
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Batch delete_files failed: {}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Batch operation failed".to_string())
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Batch operation failed".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
// Create custom response for string IDs
|
||||
@@ -331,7 +340,10 @@ pub async fn delete_folders_batch(
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Batch delete_folders failed: {}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Batch operation failed".to_string())
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Batch operation failed".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
// Create custom response for string IDs
|
||||
@@ -399,7 +411,10 @@ pub async fn create_folders_batch(
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Batch create_folders failed: {}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Batch operation failed".to_string())
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Batch operation failed".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
// Convert result to DTO
|
||||
@@ -452,7 +467,10 @@ pub async fn get_files_batch(
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Batch get_files failed: {}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Batch operation failed".to_string())
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Batch operation failed".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
// Convert result to DTO
|
||||
@@ -505,7 +523,10 @@ pub async fn get_folders_batch(
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Batch get_folders failed: {}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Batch operation failed".to_string())
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Batch operation failed".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
// Convert result to DTO
|
||||
@@ -690,7 +711,10 @@ pub async fn move_folders_batch(
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Batch move_folders failed: {}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Batch operation failed".to_string())
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Batch operation failed".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let response: BatchOperationResponse<FolderDto> = result.into();
|
||||
@@ -727,7 +751,10 @@ pub async fn download_batch(
|
||||
if combined_size > MAX_BATCH_SIZE {
|
||||
return Err((
|
||||
StatusCode::BAD_REQUEST,
|
||||
format!("Batch size {} exceeds maximum of {}", combined_size, MAX_BATCH_SIZE),
|
||||
format!(
|
||||
"Batch size {} exceeds maximum of {}",
|
||||
combined_size, MAX_BATCH_SIZE
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -737,7 +764,10 @@ pub async fn download_batch(
|
||||
.await
|
||||
.map_err(|e| {
|
||||
tracing::error!("Batch download ZIP failed: {}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Batch download failed".to_string())
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Batch download failed".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
// Read file size for Content-Length before splitting ownership
|
||||
|
||||
@@ -190,7 +190,13 @@ impl ChunkedUploadHandler {
|
||||
});
|
||||
|
||||
match chunked_service
|
||||
.upload_chunk(&upload_id, &auth_user.id, params.chunk_index, body, checksum)
|
||||
.upload_chunk(
|
||||
&upload_id,
|
||||
&auth_user.id,
|
||||
params.chunk_index,
|
||||
body,
|
||||
checksum,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(response) => {
|
||||
@@ -213,7 +219,7 @@ impl ChunkedUploadHandler {
|
||||
.unwrap()
|
||||
.into_response()
|
||||
}
|
||||
Err(e) => AppError::from(e).into_response()
|
||||
Err(e) => AppError::from(e).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,7 +267,10 @@ impl ChunkedUploadHandler {
|
||||
|
||||
// Assemble chunks (hash-on-write: SHA-256 computed during assembly)
|
||||
let (assembled_path, filename, folder_id, content_type, total_size, hash) =
|
||||
match chunked_service.complete_upload(&upload_id, &auth_user.id).await {
|
||||
match chunked_service
|
||||
.complete_upload(&upload_id, &auth_user.id)
|
||||
.await
|
||||
{
|
||||
Ok(result) => result,
|
||||
Err(e) => {
|
||||
return AppError::from(e).into_response();
|
||||
@@ -289,7 +298,9 @@ impl ChunkedUploadHandler {
|
||||
{
|
||||
Ok(file) => {
|
||||
// Cleanup session
|
||||
let _ = chunked_service.finalize_upload(&upload_id, &auth_user.id).await;
|
||||
let _ = chunked_service
|
||||
.finalize_upload(&upload_id, &auth_user.id)
|
||||
.await;
|
||||
|
||||
tracing::info!(
|
||||
"✅ CHUNKED UPLOAD COMPLETE: {} (ID: {}, {} bytes)",
|
||||
@@ -311,8 +322,7 @@ impl ChunkedUploadHandler {
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Failed to create file from assembled upload: {:?}", e);
|
||||
AppError::internal_error(format!("Failed to create file: {}", e))
|
||||
.into_response()
|
||||
AppError::internal_error(format!("Failed to create file: {}", e)).into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -327,10 +337,14 @@ impl ChunkedUploadHandler {
|
||||
) -> impl IntoResponse {
|
||||
let chunked_service = &state.core.chunked_upload_service;
|
||||
|
||||
match chunked_service.cancel_upload(&upload_id, &auth_user.id).await {
|
||||
match chunked_service
|
||||
.cancel_upload(&upload_id, &auth_user.id)
|
||||
.await
|
||||
{
|
||||
Ok(_) => StatusCode::NO_CONTENT.into_response(),
|
||||
Err(e) => AppError::internal_error(format!("Failed to cancel upload: {}", e))
|
||||
.into_response(),
|
||||
Err(e) => {
|
||||
AppError::internal_error(format!("Failed to cancel upload: {}", e)).into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,9 +231,7 @@ impl DedupHandler {
|
||||
return Response::builder()
|
||||
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
.header(header::CONTENT_TYPE, "application/json")
|
||||
.body(Body::from(
|
||||
r#"{"error": "Upload failed"}"#,
|
||||
))
|
||||
.body(Body::from(r#"{"error": "Upload failed"}"#))
|
||||
.unwrap()
|
||||
.into_response();
|
||||
}
|
||||
@@ -408,9 +406,7 @@ impl DedupHandler {
|
||||
return Response::builder()
|
||||
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
.header(header::CONTENT_TYPE, "application/json")
|
||||
.body(Body::from(
|
||||
r#"{"error": "Verification failed"}"#,
|
||||
))
|
||||
.body(Body::from(r#"{"error": "Verification failed"}"#))
|
||||
.unwrap()
|
||||
.into_response();
|
||||
}
|
||||
|
||||
@@ -106,7 +106,11 @@ impl FileHandler {
|
||||
if let Some(ref fid) = folder_id {
|
||||
use crate::application::ports::inbound::FolderUseCase;
|
||||
let folder_service = &state.applications.folder_service;
|
||||
if folder_service.get_folder_owned(fid, &auth_user.id).await.is_err() {
|
||||
if folder_service
|
||||
.get_folder_owned(fid, &auth_user.id)
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
tracing::warn!(
|
||||
"⛔ UPLOAD REJECTED (IDOR): user='{}' attempted upload to folder '{}' owned by another user",
|
||||
auth_user.username,
|
||||
@@ -323,7 +327,12 @@ impl FileHandler {
|
||||
}
|
||||
|
||||
// Resolve the actual blob path on disk (not the logical file path).
|
||||
let blob_hash = match state.repositories.file_read_repository.get_blob_hash(&id).await {
|
||||
let blob_hash = match state
|
||||
.repositories
|
||||
.file_read_repository
|
||||
.get_blob_hash(&id)
|
||||
.await
|
||||
{
|
||||
Ok(h) => h,
|
||||
Err(err) => {
|
||||
return (
|
||||
@@ -353,10 +362,8 @@ impl FileHandler {
|
||||
.unwrap()
|
||||
.into_response()
|
||||
}
|
||||
Err(err) => {
|
||||
AppError::internal_error(format!("Thumbnail generation failed: {}", err))
|
||||
.into_response()
|
||||
}
|
||||
Err(err) => AppError::internal_error(format!("Thumbnail generation failed: {}", err))
|
||||
.into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -529,9 +536,7 @@ impl FileHandler {
|
||||
.unwrap()
|
||||
.into_response(),
|
||||
},
|
||||
Err(err) => {
|
||||
AppError::from(err).into_response()
|
||||
}
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -581,9 +586,7 @@ impl FileHandler {
|
||||
.insert(header::ETAG, header::HeaderValue::from_str(&etag).unwrap());
|
||||
resp
|
||||
}
|
||||
Err(err) => {
|
||||
AppError::from(err).into_response()
|
||||
}
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -664,7 +667,7 @@ impl FileHandler {
|
||||
|
||||
match result {
|
||||
Ok(_) => StatusCode::NO_CONTENT.into_response(),
|
||||
Err(err) => AppError::from(err).into_response()
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -696,7 +699,7 @@ impl FileHandler {
|
||||
let mgmt = &state.applications.file_management_service;
|
||||
match mgmt.rename_file_owned(&id, &auth_user.id, &new_name).await {
|
||||
Ok(file_dto) => (StatusCode::OK, Json(file_dto)).into_response(),
|
||||
Err(err) => AppError::from(err).into_response()
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -716,7 +719,7 @@ impl FileHandler {
|
||||
.await
|
||||
{
|
||||
Ok(file) => (StatusCode::OK, Json(file)).into_response(),
|
||||
Err(err) => AppError::from(err).into_response()
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -735,7 +738,7 @@ impl FileHandler {
|
||||
let mgmt = &state.applications.file_management_service;
|
||||
match mgmt.move_file_owned(&id, &auth_user.id, folder_id).await {
|
||||
Ok(file_dto) => (StatusCode::OK, Json(file_dto)).into_response(),
|
||||
Err(err) => AppError::from(err).into_response()
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -794,9 +797,7 @@ impl FileHandler {
|
||||
})
|
||||
.collect();
|
||||
|
||||
format!(
|
||||
"{disposition}; filename=\"{ascii_safe}\"; filename*=UTF-8''{encoded}"
|
||||
)
|
||||
format!("{disposition}; filename=\"{ascii_safe}\"; filename*=UTF-8''{encoded}")
|
||||
}
|
||||
|
||||
/// Build a 201 Created JSON response.
|
||||
|
||||
@@ -70,19 +70,24 @@ 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() {
|
||||
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();
|
||||
return AppError::not_found(format!("Parent folder not found: {}", parent_id))
|
||||
.into_response();
|
||||
}
|
||||
}
|
||||
|
||||
match service.create_folder(dto).await {
|
||||
Ok(folder) => (StatusCode::CREATED, Json(folder)).into_response(),
|
||||
Err(err) => AppError::from(err).into_response()
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +114,7 @@ impl FolderHandler {
|
||||
}
|
||||
(StatusCode::OK, Json(folder)).into_response()
|
||||
}
|
||||
Err(err) => AppError::from(err).into_response()
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +159,7 @@ impl FolderHandler {
|
||||
.await
|
||||
{
|
||||
Ok(paginated_result) => (StatusCode::OK, Json(paginated_result)).into_response(),
|
||||
Err(err) => AppError::from(err).into_response()
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +176,7 @@ impl FolderHandler {
|
||||
.await
|
||||
{
|
||||
Ok(folders) => (StatusCode::OK, Json(folders)).into_response(),
|
||||
Err(err) => AppError::from(err).into_response()
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,7 +242,7 @@ impl FolderHandler {
|
||||
.insert(header::ETAG, header::HeaderValue::from_str(&etag).unwrap());
|
||||
resp
|
||||
}
|
||||
(Err(err), _) | (_, Err(err)) => AppError::from(err).into_response()
|
||||
(Err(err), _) | (_, Err(err)) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,7 +255,7 @@ impl FolderHandler {
|
||||
) -> impl IntoResponse {
|
||||
match service.rename_folder(&id, dto, &auth_user.id).await {
|
||||
Ok(folder) => (StatusCode::OK, Json(folder)).into_response(),
|
||||
Err(err) => AppError::from(err).into_response()
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,7 +268,7 @@ impl FolderHandler {
|
||||
) -> impl IntoResponse {
|
||||
match service.move_folder(&id, dto, &auth_user.id).await {
|
||||
Ok(folder) => (StatusCode::OK, Json(folder)).into_response(),
|
||||
Err(err) => AppError::from(err).into_response()
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +280,7 @@ impl FolderHandler {
|
||||
) -> impl IntoResponse {
|
||||
match service.delete_folder(&id, &auth_user.id).await {
|
||||
Ok(_) => StatusCode::NO_CONTENT.into_response(),
|
||||
Err(err) => AppError::from(err).into_response()
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,9 +318,7 @@ impl FolderHandler {
|
||||
tracing::info!("Folder permanently deleted: {}", id);
|
||||
StatusCode::NO_CONTENT.into_response()
|
||||
}
|
||||
Err(err) => {
|
||||
AppError::from(err).into_response()
|
||||
}
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,12 +40,9 @@ pub async fn create_shared_link(
|
||||
auth_user: AuthUser,
|
||||
Json(dto): Json<CreateShareDto>,
|
||||
) -> impl IntoResponse {
|
||||
match share_use_case
|
||||
.create_shared_link(&auth_user.id, dto)
|
||||
.await
|
||||
{
|
||||
match share_use_case.create_shared_link(&auth_user.id, dto).await {
|
||||
Ok(share) => (StatusCode::CREATED, Json(share)).into_response(),
|
||||
Err(err) => AppError::from(err).into_response()
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +54,7 @@ pub async fn get_shared_link(
|
||||
) -> impl IntoResponse {
|
||||
match share_use_case.get_shared_link(&id, &auth_user.id).await {
|
||||
Ok(share) => (StatusCode::OK, Json(share)).into_response(),
|
||||
Err(err) => AppError::from(err).into_response()
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +113,7 @@ pub async fn update_shared_link(
|
||||
.await
|
||||
{
|
||||
Ok(share) => (StatusCode::OK, Json(share)).into_response(),
|
||||
Err(err) => AppError::from(err).into_response()
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,12 +123,9 @@ pub async fn delete_shared_link(
|
||||
auth_user: AuthUser,
|
||||
Path(id): Path<String>,
|
||||
) -> impl IntoResponse {
|
||||
match share_use_case
|
||||
.delete_shared_link(&id, &auth_user.id)
|
||||
.await
|
||||
{
|
||||
match share_use_case.delete_shared_link(&id, &auth_user.id).await {
|
||||
Ok(_) => StatusCode::NO_CONTENT.into_response(),
|
||||
Err(err) => AppError::from(err).into_response()
|
||||
Err(err) => AppError::from(err).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,8 +154,7 @@ pub async fn access_shared_item(
|
||||
.into_response();
|
||||
}
|
||||
if err.message.contains("expired") {
|
||||
return AppError::new(StatusCode::GONE, err.message, "Expired")
|
||||
.into_response();
|
||||
return AppError::new(StatusCode::GONE, err.message, "Expired").into_response();
|
||||
}
|
||||
}
|
||||
AppError::from(err).into_response()
|
||||
@@ -183,8 +176,7 @@ pub async fn verify_shared_item_password(
|
||||
Err(err) => {
|
||||
if err.kind == ErrorKind::AccessDenied {
|
||||
if err.message.contains("expired") {
|
||||
return AppError::new(StatusCode::GONE, err.message, "Expired")
|
||||
.into_response();
|
||||
return AppError::new(StatusCode::GONE, err.message, "Expired").into_response();
|
||||
}
|
||||
if err.message.contains("password") {
|
||||
return AppError::unauthorized("Invalid password").into_response();
|
||||
|
||||
@@ -1161,10 +1161,7 @@ async fn handle_move(
|
||||
|
||||
// Resolve source: single-query when PathResolver is available (user-scoped)
|
||||
if let Some(resolver) = &state.path_resolver {
|
||||
match resolver
|
||||
.resolve_path_for_user(&source_path, &user.id)
|
||||
.await
|
||||
{
|
||||
match resolver.resolve_path_for_user(&source_path, &user.id).await {
|
||||
Ok(ResolvedResource::Folder(folder)) => {
|
||||
let dest_folder_name = destination_path
|
||||
.split('/')
|
||||
@@ -1183,7 +1180,11 @@ async fn handle_move(
|
||||
match folder_service.get_folder_by_path(dest_parent_path).await {
|
||||
Ok(parent) => {
|
||||
// SECURITY: verify destination parent belongs to caller (V-08)
|
||||
assert_owner(parent.owner_id.as_deref(), &user.id, dest_parent_path)?;
|
||||
assert_owner(
|
||||
parent.owner_id.as_deref(),
|
||||
&user.id,
|
||||
dest_parent_path,
|
||||
)?;
|
||||
Some(parent.id)
|
||||
}
|
||||
Err(_) => None,
|
||||
@@ -1228,7 +1229,10 @@ async fn handle_move(
|
||||
|
||||
if source_parent_path != dest_parent_path {
|
||||
// SECURITY: verify destination parent belongs to caller (V-08)
|
||||
if !dest_parent_path.is_empty() && let Ok(parent) = folder_service.get_folder_by_path(dest_parent_path).await {
|
||||
if !dest_parent_path.is_empty()
|
||||
&& let Ok(parent) =
|
||||
folder_service.get_folder_by_path(dest_parent_path).await
|
||||
{
|
||||
assert_owner(parent.owner_id.as_deref(), &user.id, dest_parent_path)?;
|
||||
}
|
||||
file_management_service
|
||||
@@ -1327,7 +1331,9 @@ async fn handle_move(
|
||||
|
||||
if source_parent_path != dest_parent_path {
|
||||
// SECURITY: verify destination parent belongs to caller (V-08)
|
||||
if !dest_parent_path.is_empty() && let Ok(parent) = folder_service.get_folder_by_path(dest_parent_path).await {
|
||||
if !dest_parent_path.is_empty()
|
||||
&& let Ok(parent) = folder_service.get_folder_by_path(dest_parent_path).await
|
||||
{
|
||||
assert_owner(parent.owner_id.as_deref(), &user.id, dest_parent_path)?;
|
||||
}
|
||||
file_management_service
|
||||
@@ -1436,10 +1442,7 @@ async fn handle_copy(
|
||||
|
||||
// Resolve source: single-query when PathResolver is available (user-scoped)
|
||||
if let Some(resolver) = &state.path_resolver {
|
||||
match resolver
|
||||
.resolve_path_for_user(&source_path, &user.id)
|
||||
.await
|
||||
{
|
||||
match resolver.resolve_path_for_user(&source_path, &user.id).await {
|
||||
Ok(ResolvedResource::Folder(folder)) => {
|
||||
let recursive = depth != "0";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user