fix: name harmonization of endpoints & ingestion security hardening

This commit is contained in:
Per Stark
2026-02-13 22:36:00 +01:00
parent f22cac891c
commit e07199adfc
15 changed files with 258 additions and 53 deletions

View File

@@ -20,6 +20,9 @@ pub enum ApiError {
#[error("Unauthorized: {0}")]
Unauthorized(String),
#[error("Payload too large: {0}")]
PayloadTooLarge(String),
}
impl From<AppError> for ApiError {
@@ -67,6 +70,13 @@ impl IntoResponse for ApiError {
status: "error".to_string(),
},
),
Self::PayloadTooLarge(message) => (
StatusCode::PAYLOAD_TOO_LARGE,
ErrorResponse {
error: message,
status: "error".to_string(),
},
),
};
(status, Json(error_response)).into_response()
@@ -132,6 +142,10 @@ mod tests {
// Test unauthorized status
let error = ApiError::Unauthorized("not allowed".to_string());
assert_status_code(error, StatusCode::UNAUTHORIZED);
// Test payload too large status
let error = ApiError::PayloadTooLarge("too big".to_string());
assert_status_code(error, StatusCode::PAYLOAD_TOO_LARGE);
}
// Alternative approach that doesn't try to parse the response body

View File

@@ -6,7 +6,7 @@ use axum::{
Router,
};
use middleware_api_auth::api_auth;
use routes::{categories::get_categories, ingress::ingest_data, liveness::live, readiness::ready};
use routes::{categories::get_categories, ingest::ingest_data, liveness::live, readiness::ready};
pub mod api_state;
pub mod error;
@@ -26,9 +26,13 @@ where
// Protected API endpoints (require auth)
let protected = Router::new()
.route("/ingress", post(ingest_data))
.route(
"/ingest",
post(ingest_data).layer(DefaultBodyLimit::max(
app_state.config.ingest_max_body_bytes,
)),
)
.route("/categories", get(get_categories))
.layer(DefaultBodyLimit::max(1024 * 1024 * 1024))
.route_layer(from_fn_with_state(app_state.clone(), api_auth));
public.merge(protected)

View File

@@ -6,6 +6,7 @@ use common::{
file_info::FileInfo, ingestion_payload::IngestionPayload, ingestion_task::IngestionTask,
user::User,
},
utils::ingest_limits::{validate_ingest_input, IngestValidationError},
};
use futures::{future::try_join_all, TryFutureExt};
use serde_json::json;
@@ -19,7 +20,7 @@ pub struct IngestParams {
pub content: Option<String>,
pub context: String,
pub category: String,
#[form_data(limit = "10000000")] // Adjust limit as needed
#[form_data(limit = "20000000")]
#[form_data(default)]
pub files: Vec<FieldData<NamedTempFile>>,
}
@@ -36,6 +37,22 @@ pub async fn ingest_data(
let category_bytes = input.category.len();
let file_count = input.files.len();
match validate_ingest_input(
&state.config,
input.content.as_deref(),
&input.context,
&input.category,
file_count,
) {
Ok(()) => {}
Err(IngestValidationError::PayloadTooLarge(message)) => {
return Err(ApiError::PayloadTooLarge(message));
}
Err(IngestValidationError::BadRequest(message)) => {
return Err(ApiError::ValidationError(message));
}
}
info!(
user_id = %user_id,
has_content,
@@ -43,7 +60,7 @@ pub async fn ingest_data(
context_bytes,
category_bytes,
file_count,
"Received ingestion request"
"Received ingest request"
);
let file_infos = try_join_all(input.files.into_iter().map(|file| {

View File

@@ -1,4 +1,4 @@
pub mod categories;
pub mod ingress;
pub mod ingest;
pub mod liveness;
pub mod readiness;