chore(/api/uploads): maked as deprecated, use now /api/files/delta/
This commit is contained in:
@@ -491,7 +491,12 @@ impl ChunkedUploadHandler {
|
|||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::error!("Failed to create file from chunked upload: {:?}", e);
|
tracing::error!("Failed to create file from chunked upload: {:?}", e);
|
||||||
AppError::internal_error(format!("Failed to create file: {}", e)).into_response()
|
// AuthZ audit #2 (2026-07-12) — route DomainError through
|
||||||
|
// `AppError::from` so graduated denial from
|
||||||
|
// `upload_file_streaming_with_perms` keeps the 403/404
|
||||||
|
// shape instead of collapsing into a 500. Sibling
|
||||||
|
// `cancel_upload_impl` at :514 already uses this pattern.
|
||||||
|
AppError::from(e).into_response()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -532,9 +537,15 @@ impl ChunkedUploadHandler {
|
|||||||
// routes.rs calls these free functions directly.
|
// routes.rs calls these free functions directly.
|
||||||
// TODO: collapse back into the impl block after a utoipa upgrade resolves the issue.
|
// TODO: collapse back into the impl block after a utoipa upgrade resolves the issue.
|
||||||
|
|
||||||
|
/// **Deprecated.** Prefer `/api/files/delta/*` — hash-first negotiation,
|
||||||
|
/// resumable, chunked. The `/api/uploads/*` family stays for backward
|
||||||
|
/// compatibility with existing clients but receives no new features.
|
||||||
#[utoipa::path(
|
#[utoipa::path(
|
||||||
post,
|
post,
|
||||||
path = "/api/uploads",
|
path = "/api/uploads",
|
||||||
|
description = "**Deprecated.** Prefer the delta-upload surface at `/api/files/delta/*` \
|
||||||
|
(hash-first negotiation, resumable, chunked). The `/api/uploads/*` family is kept for \
|
||||||
|
backward compatibility with existing clients but is no longer receiving new features.",
|
||||||
request_body(content = CreateUploadRequest, content_type = "application/json", description = "Upload session parameters"),
|
request_body(content = CreateUploadRequest, content_type = "application/json", description = "Upload session parameters"),
|
||||||
responses(
|
responses(
|
||||||
(status = 201, description = "Upload session created", body = crate::application::ports::chunked_upload_ports::CreateUploadResponseDto),
|
(status = 201, description = "Upload session created", body = crate::application::ports::chunked_upload_ports::CreateUploadResponseDto),
|
||||||
@@ -544,6 +555,7 @@ impl ChunkedUploadHandler {
|
|||||||
tag = "uploads",
|
tag = "uploads",
|
||||||
security(("bearerAuth" = []))
|
security(("bearerAuth" = []))
|
||||||
)]
|
)]
|
||||||
|
#[deprecated(note = "prefer /api/files/delta/*")]
|
||||||
pub async fn create_upload(
|
pub async fn create_upload(
|
||||||
state: State<Arc<AppState>>,
|
state: State<Arc<AppState>>,
|
||||||
auth_user: AuthUser,
|
auth_user: AuthUser,
|
||||||
@@ -552,9 +564,11 @@ pub async fn create_upload(
|
|||||||
ChunkedUploadHandler::create_upload_impl(state, auth_user, request).await
|
ChunkedUploadHandler::create_upload_impl(state, auth_user, request).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// **Deprecated.** Prefer `/api/files/delta/*` — see `create_upload`.
|
||||||
#[utoipa::path(
|
#[utoipa::path(
|
||||||
patch,
|
patch,
|
||||||
path = "/api/uploads/{upload_id}",
|
path = "/api/uploads/{upload_id}",
|
||||||
|
description = "**Deprecated.** See `POST /api/uploads` for the migration note.",
|
||||||
params(
|
params(
|
||||||
("upload_id" = String, Path, description = "Upload session ID"),
|
("upload_id" = String, Path, description = "Upload session ID"),
|
||||||
("chunk_index" = usize, Query, description = "Zero-based chunk index"),
|
("chunk_index" = usize, Query, description = "Zero-based chunk index"),
|
||||||
@@ -583,6 +597,7 @@ pub async fn create_upload(
|
|||||||
tag = "uploads",
|
tag = "uploads",
|
||||||
security(("bearerAuth" = []))
|
security(("bearerAuth" = []))
|
||||||
)]
|
)]
|
||||||
|
#[deprecated(note = "prefer /api/files/delta/*")]
|
||||||
pub async fn upload_chunk(
|
pub async fn upload_chunk(
|
||||||
State(state): State<Arc<AppState>>,
|
State(state): State<Arc<AppState>>,
|
||||||
auth_user: AuthUser,
|
auth_user: AuthUser,
|
||||||
@@ -696,9 +711,11 @@ pub async fn upload_chunk(
|
|||||||
.into_response()
|
.into_response()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// **Deprecated.** Prefer `/api/files/delta/*` — see `create_upload`.
|
||||||
#[utoipa::path(
|
#[utoipa::path(
|
||||||
head,
|
head,
|
||||||
path = "/api/uploads/{upload_id}",
|
path = "/api/uploads/{upload_id}",
|
||||||
|
description = "**Deprecated.** See `POST /api/uploads` for the migration note.",
|
||||||
params(
|
params(
|
||||||
("upload_id" = String, Path, description = "Upload session ID"),
|
("upload_id" = String, Path, description = "Upload session ID"),
|
||||||
),
|
),
|
||||||
@@ -709,6 +726,7 @@ pub async fn upload_chunk(
|
|||||||
tag = "uploads",
|
tag = "uploads",
|
||||||
security(("bearerAuth" = []))
|
security(("bearerAuth" = []))
|
||||||
)]
|
)]
|
||||||
|
#[deprecated(note = "prefer /api/files/delta/*")]
|
||||||
pub async fn get_upload_status(
|
pub async fn get_upload_status(
|
||||||
state: State<Arc<AppState>>,
|
state: State<Arc<AppState>>,
|
||||||
auth_user: AuthUser,
|
auth_user: AuthUser,
|
||||||
@@ -717,9 +735,11 @@ pub async fn get_upload_status(
|
|||||||
ChunkedUploadHandler::get_upload_status_impl(state, auth_user, path).await
|
ChunkedUploadHandler::get_upload_status_impl(state, auth_user, path).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// **Deprecated.** Prefer `/api/files/delta/*` — see `create_upload`.
|
||||||
#[utoipa::path(
|
#[utoipa::path(
|
||||||
post,
|
post,
|
||||||
path = "/api/uploads/{upload_id}/complete",
|
path = "/api/uploads/{upload_id}/complete",
|
||||||
|
description = "**Deprecated.** See `POST /api/uploads` for the migration note.",
|
||||||
params(
|
params(
|
||||||
("upload_id" = String, Path, description = "Upload session ID"),
|
("upload_id" = String, Path, description = "Upload session ID"),
|
||||||
),
|
),
|
||||||
@@ -744,6 +764,7 @@ pub async fn get_upload_status(
|
|||||||
tag = "uploads",
|
tag = "uploads",
|
||||||
security(("bearerAuth" = []))
|
security(("bearerAuth" = []))
|
||||||
)]
|
)]
|
||||||
|
#[deprecated(note = "prefer /api/files/delta/*")]
|
||||||
pub async fn complete_upload(
|
pub async fn complete_upload(
|
||||||
state: State<Arc<AppState>>,
|
state: State<Arc<AppState>>,
|
||||||
auth_user: AuthUser,
|
auth_user: AuthUser,
|
||||||
@@ -757,9 +778,11 @@ pub async fn complete_upload(
|
|||||||
ChunkedUploadHandler::complete_upload_impl(state, auth_user, path, req).await
|
ChunkedUploadHandler::complete_upload_impl(state, auth_user, path, req).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// **Deprecated.** Prefer `/api/files/delta/*` — see `create_upload`.
|
||||||
#[utoipa::path(
|
#[utoipa::path(
|
||||||
delete,
|
delete,
|
||||||
path = "/api/uploads/{upload_id}",
|
path = "/api/uploads/{upload_id}",
|
||||||
|
description = "**Deprecated.** See `POST /api/uploads` for the migration note.",
|
||||||
params(
|
params(
|
||||||
("upload_id" = String, Path, description = "Upload session ID"),
|
("upload_id" = String, Path, description = "Upload session ID"),
|
||||||
),
|
),
|
||||||
@@ -770,6 +793,7 @@ pub async fn complete_upload(
|
|||||||
tag = "uploads",
|
tag = "uploads",
|
||||||
security(("bearerAuth" = []))
|
security(("bearerAuth" = []))
|
||||||
)]
|
)]
|
||||||
|
#[deprecated(note = "prefer /api/files/delta/*")]
|
||||||
pub async fn cancel_upload(
|
pub async fn cancel_upload(
|
||||||
state: State<Arc<AppState>>,
|
state: State<Arc<AppState>>,
|
||||||
auth_user: AuthUser,
|
auth_user: AuthUser,
|
||||||
|
|||||||
@@ -52,6 +52,11 @@ async fn get_openapi_spec() -> AxumJson<utoipa::openapi::OpenApi> {
|
|||||||
|
|
||||||
use crate::interfaces::api::handlers::admin_handler;
|
use crate::interfaces::api::handlers::admin_handler;
|
||||||
use crate::interfaces::api::handlers::batch_handler::{self, BatchHandlerState};
|
use crate::interfaces::api::handlers::batch_handler::{self, BatchHandlerState};
|
||||||
|
// `chunked_upload_handler::*` are marked `#[deprecated]` (prefer
|
||||||
|
// `/api/files/delta/*`); the router still needs to reference them
|
||||||
|
// until clients migrate. See the `chunked_upload_router` block
|
||||||
|
// below for the local `#[allow(deprecated)]`.
|
||||||
|
#[allow(deprecated)]
|
||||||
use crate::interfaces::api::handlers::chunked_upload_handler::{
|
use crate::interfaces::api::handlers::chunked_upload_handler::{
|
||||||
cancel_upload, complete_upload, create_upload, get_upload_status, upload_chunk,
|
cancel_upload, complete_upload, create_upload, get_upload_status, upload_chunk,
|
||||||
};
|
};
|
||||||
@@ -368,6 +373,13 @@ pub fn create_api_routes(app_state: &Arc<AppState>) -> Router<Arc<AppState>> {
|
|||||||
// Create routes for chunked uploads (large files >10MB).
|
// Create routes for chunked uploads (large files >10MB).
|
||||||
// All five handlers are free functions — see chunked_upload_handler.rs for why
|
// All five handlers are free functions — see chunked_upload_handler.rs for why
|
||||||
// #[utoipa::path] cannot be applied to ChunkedUploadHandler impl methods directly.
|
// #[utoipa::path] cannot be applied to ChunkedUploadHandler impl methods directly.
|
||||||
|
//
|
||||||
|
// Each handler carries `#[deprecated]` so utoipa marks the OpenAPI paths
|
||||||
|
// deprecated (Swagger UI shows the strikethrough + banner) and existing
|
||||||
|
// callers get a compile-time nudge to migrate to `/api/files/delta/*`.
|
||||||
|
// The route registration itself has to keep referencing them until the
|
||||||
|
// clients migrate off, so we suppress the local `deprecated` lint here.
|
||||||
|
#[allow(deprecated)]
|
||||||
let chunked_upload_router = Router::new()
|
let chunked_upload_router = Router::new()
|
||||||
.route("/", post(create_upload))
|
.route("/", post(create_upload))
|
||||||
.route("/{upload_id}", axum::routing::patch(upload_chunk))
|
.route("/{upload_id}", axum::routing::patch(upload_chunk))
|
||||||
|
|||||||
Reference in New Issue
Block a user