Apply cargo fmt formatting to fix CI/CD fmt job
This commit is contained in:
@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
|
||||
use tracing::{error, info, warn};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::jobs::manager::{JobManager, JobOperation, JobStatus, Job};
|
||||
use crate::jobs::manager::{Job, JobManager, JobOperation, JobStatus};
|
||||
|
||||
use super::packages::{ApiResponse, JobResponseData};
|
||||
|
||||
|
||||
@ -7,12 +7,12 @@
|
||||
//! - jobs: Job management endpoints
|
||||
//! - websocket: Real-time job status streaming
|
||||
|
||||
pub mod jobs;
|
||||
pub mod packages;
|
||||
pub mod patches;
|
||||
pub mod system;
|
||||
pub mod jobs;
|
||||
pub mod websocket;
|
||||
|
||||
// Re-export commonly used types
|
||||
pub use packages::{ApiResponse, ApiError};
|
||||
pub use packages::{ApiError, ApiResponse};
|
||||
pub use websocket::{WsClientMessage, WsServerMessage};
|
||||
|
||||
@ -14,7 +14,7 @@ use tracing::{error, info, warn};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::jobs::manager::{JobManager, JobOperation, JobStatus};
|
||||
use crate::packages::{Package, PackageManagerBackend, PackageSpec, InstallOptions};
|
||||
use crate::packages::{InstallOptions, Package, PackageManagerBackend, PackageSpec};
|
||||
|
||||
/// Maximum allowed length for package names
|
||||
const MAX_PACKAGE_NAME_LENGTH: usize = 256;
|
||||
@ -25,7 +25,10 @@ fn validate_package_name(name: &str) -> Result<(), String> {
|
||||
return Err("Package name cannot be empty".to_string());
|
||||
}
|
||||
if name.len() > MAX_PACKAGE_NAME_LENGTH {
|
||||
return Err(format!("Package name exceeds maximum length of {} characters", MAX_PACKAGE_NAME_LENGTH));
|
||||
return Err(format!(
|
||||
"Package name exceeds maximum length of {} characters",
|
||||
MAX_PACKAGE_NAME_LENGTH
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -59,7 +62,12 @@ impl<T: Serialize> ApiResponse<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn error(code: &str, message: &str, details: Option<serde_json::Value>, retryable: bool) -> Self {
|
||||
pub fn error(
|
||||
code: &str,
|
||||
message: &str,
|
||||
details: Option<serde_json::Value>,
|
||||
retryable: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
success: false,
|
||||
request_id: Uuid::new_v4().to_string(),
|
||||
@ -134,13 +142,11 @@ pub async fn list_packages(
|
||||
Ok(mut packages) => {
|
||||
// Apply filters
|
||||
if let Some(status) = &query.status {
|
||||
packages.retain(|p| {
|
||||
match status.as_str() {
|
||||
"installed" => p.status == crate::packages::PackageStatus::Installed,
|
||||
"upgradable" => p.upgradable,
|
||||
"available" => p.status == crate::packages::PackageStatus::Available,
|
||||
_ => true,
|
||||
}
|
||||
packages.retain(|p| match status.as_str() {
|
||||
"installed" => p.status == crate::packages::PackageStatus::Installed,
|
||||
"upgradable" => p.upgradable,
|
||||
"available" => p.status == crate::packages::PackageStatus::Available,
|
||||
_ => true,
|
||||
});
|
||||
}
|
||||
|
||||
@ -153,7 +159,7 @@ pub async fn list_packages(
|
||||
// Apply sorting
|
||||
let sort_field = query.sort.as_deref().unwrap_or("name");
|
||||
let ascending = query.order.as_deref().unwrap_or("asc") == "asc";
|
||||
|
||||
|
||||
packages.sort_by(|a, b| {
|
||||
let cmp = match sort_field {
|
||||
"name" => a.name.cmp(&b.name),
|
||||
@ -161,7 +167,11 @@ pub async fn list_packages(
|
||||
"status" => format!("{:?}", a.status).cmp(&format!("{:?}", b.status)),
|
||||
_ => a.name.cmp(&b.name),
|
||||
};
|
||||
if ascending { cmp } else { cmp.reverse() }
|
||||
if ascending {
|
||||
cmp
|
||||
} else {
|
||||
cmp.reverse()
|
||||
}
|
||||
});
|
||||
|
||||
let total = packages.len();
|
||||
@ -200,12 +210,7 @@ pub async fn get_package(
|
||||
|
||||
// VULN-001, VULN-003: Validate package name (length and empty string)
|
||||
if let Err(e) = validate_package_name(&package_name) {
|
||||
let response = ApiResponse::<()>::error(
|
||||
"VALIDATION_ERROR",
|
||||
&e,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
let response = ApiResponse::<()>::error("VALIDATION_ERROR", &e, None, false);
|
||||
return HttpResponse::BadRequest().json(response);
|
||||
}
|
||||
|
||||
@ -252,19 +257,17 @@ pub async fn install_packages(
|
||||
|
||||
// VULN-001, VULN-003: Validate all package names (length and empty string)
|
||||
if let Err(e) = validate_package_names(&body.packages) {
|
||||
let response = ApiResponse::<()>::error(
|
||||
"VALIDATION_ERROR",
|
||||
&e,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
let response = ApiResponse::<()>::error("VALIDATION_ERROR", &e, None, false);
|
||||
return HttpResponse::BadRequest().json(response);
|
||||
}
|
||||
|
||||
info!(request_id = %request_id, packages = ?package_names, "Installing packages");
|
||||
|
||||
// Create async job
|
||||
match job_manager.create_job(JobOperation::Install, package_names.clone()).await {
|
||||
match job_manager
|
||||
.create_job(JobOperation::Install, package_names.clone())
|
||||
.await
|
||||
{
|
||||
Ok(job_id) => {
|
||||
// Spawn background task to execute the installation
|
||||
let backend_clone = backend.clone();
|
||||
@ -274,10 +277,19 @@ pub async fn install_packages(
|
||||
|
||||
tokio::spawn(async move {
|
||||
let job_id_clone = job_id;
|
||||
|
||||
|
||||
// Update job to running
|
||||
let _ = job_manager_clone.update_job(&job_id_clone, JobStatus::Running, Some(0), Some("Starting installation...".to_string())).await;
|
||||
let _ = job_manager_clone.add_job_log(&job_id_clone, "Job started".to_string()).await;
|
||||
let _ = job_manager_clone
|
||||
.update_job(
|
||||
&job_id_clone,
|
||||
JobStatus::Running,
|
||||
Some(0),
|
||||
Some("Starting installation...".to_string()),
|
||||
)
|
||||
.await;
|
||||
let _ = job_manager_clone
|
||||
.add_job_log(&job_id_clone, "Job started".to_string())
|
||||
.await;
|
||||
|
||||
// Execute installation
|
||||
match backend_clone.install_packages(&packages, &options) {
|
||||
@ -286,7 +298,9 @@ pub async fn install_packages(
|
||||
info!(job_id = %job_id_clone, "Package installation completed");
|
||||
}
|
||||
Err(e) => {
|
||||
let _ = job_manager_clone.fail_job(&job_id_clone, e.to_string()).await;
|
||||
let _ = job_manager_clone
|
||||
.fail_job(&job_id_clone, e.to_string())
|
||||
.await;
|
||||
error!(job_id = %job_id_clone, error = %e, "Package installation failed");
|
||||
}
|
||||
}
|
||||
@ -328,19 +342,17 @@ pub async fn update_package(
|
||||
|
||||
// VULN-001, VULN-003: Validate package name (length and empty string)
|
||||
if let Err(e) = validate_package_name(&package_name) {
|
||||
let response = ApiResponse::<()>::error(
|
||||
"VALIDATION_ERROR",
|
||||
&e,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
let response = ApiResponse::<()>::error("VALIDATION_ERROR", &e, None, false);
|
||||
return HttpResponse::BadRequest().json(response);
|
||||
}
|
||||
|
||||
info!(request_id = %request_id, package = %package_name, "Updating package");
|
||||
|
||||
// Create async job
|
||||
match job_manager.create_job(JobOperation::Update, vec![package_name.clone()]).await {
|
||||
match job_manager
|
||||
.create_job(JobOperation::Update, vec![package_name.clone()])
|
||||
.await
|
||||
{
|
||||
Ok(job_id) => {
|
||||
// Spawn background task to execute the update
|
||||
let backend_clone = backend.clone();
|
||||
@ -349,10 +361,19 @@ pub async fn update_package(
|
||||
|
||||
tokio::spawn(async move {
|
||||
let job_id_clone = job_id;
|
||||
|
||||
|
||||
// Update job to running
|
||||
let _ = job_manager_clone.update_job(&job_id_clone, JobStatus::Running, Some(0), Some("Starting update...".to_string())).await;
|
||||
let _ = job_manager_clone.add_job_log(&job_id_clone, "Job started".to_string()).await;
|
||||
let _ = job_manager_clone
|
||||
.update_job(
|
||||
&job_id_clone,
|
||||
JobStatus::Running,
|
||||
Some(0),
|
||||
Some("Starting update...".to_string()),
|
||||
)
|
||||
.await;
|
||||
let _ = job_manager_clone
|
||||
.add_job_log(&job_id_clone, "Job started".to_string())
|
||||
.await;
|
||||
|
||||
// Execute update
|
||||
match backend_clone.update_package(&pkg_name) {
|
||||
@ -361,7 +382,9 @@ pub async fn update_package(
|
||||
info!(job_id = %job_id_clone, package = %pkg_name, "Package update completed");
|
||||
}
|
||||
Err(e) => {
|
||||
let _ = job_manager_clone.fail_job(&job_id_clone, e.to_string()).await;
|
||||
let _ = job_manager_clone
|
||||
.fail_job(&job_id_clone, e.to_string())
|
||||
.await;
|
||||
error!(job_id = %job_id_clone, package = %pkg_name, error = %e, "Package update failed");
|
||||
}
|
||||
}
|
||||
@ -403,17 +426,15 @@ pub async fn remove_package(
|
||||
|
||||
// VULN-001, VULN-003: Validate package name (length and empty string)
|
||||
if let Err(e) = validate_package_name(&package_name) {
|
||||
let response = ApiResponse::<()>::error(
|
||||
"VALIDATION_ERROR",
|
||||
&e,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
let response = ApiResponse::<()>::error("VALIDATION_ERROR", &e, None, false);
|
||||
return HttpResponse::BadRequest().json(response);
|
||||
}
|
||||
|
||||
info!(request_id = %request_id, package = %package_name, "Removing package");
|
||||
match job_manager.create_job(JobOperation::Remove, vec![package_name.clone()]).await {
|
||||
match job_manager
|
||||
.create_job(JobOperation::Remove, vec![package_name.clone()])
|
||||
.await
|
||||
{
|
||||
Ok(job_id) => {
|
||||
// Spawn background task to execute the removal
|
||||
let backend_clone = backend.clone();
|
||||
@ -422,10 +443,19 @@ pub async fn remove_package(
|
||||
|
||||
tokio::spawn(async move {
|
||||
let job_id_clone = job_id;
|
||||
|
||||
|
||||
// Update job to running
|
||||
let _ = job_manager_clone.update_job(&job_id_clone, JobStatus::Running, Some(0), Some("Starting removal...".to_string())).await;
|
||||
let _ = job_manager_clone.add_job_log(&job_id_clone, "Job started".to_string()).await;
|
||||
let _ = job_manager_clone
|
||||
.update_job(
|
||||
&job_id_clone,
|
||||
JobStatus::Running,
|
||||
Some(0),
|
||||
Some("Starting removal...".to_string()),
|
||||
)
|
||||
.await;
|
||||
let _ = job_manager_clone
|
||||
.add_job_log(&job_id_clone, "Job started".to_string())
|
||||
.await;
|
||||
|
||||
// Execute removal (purge=false for standard removal)
|
||||
match backend_clone.remove_package(&pkg_name, false) {
|
||||
@ -434,7 +464,9 @@ pub async fn remove_package(
|
||||
info!(job_id = %job_id_clone, package = %pkg_name, "Package removal completed");
|
||||
}
|
||||
Err(e) => {
|
||||
let _ = job_manager_clone.fail_job(&job_id_clone, e.to_string()).await;
|
||||
let _ = job_manager_clone
|
||||
.fail_job(&job_id_clone, e.to_string())
|
||||
.await;
|
||||
error!(job_id = %job_id_clone, package = %pkg_name, error = %e, "Package removal failed");
|
||||
}
|
||||
}
|
||||
@ -490,7 +522,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_api_response_error() {
|
||||
let response: ApiResponse<()> = ApiResponse::error("TEST_CODE", "Test message", None, false);
|
||||
let response: ApiResponse<()> =
|
||||
ApiResponse::error("TEST_CODE", "Test message", None, false);
|
||||
assert!(!response.success);
|
||||
assert!(response.error.is_some());
|
||||
assert_eq!(response.error.unwrap().code, "TEST_CODE");
|
||||
|
||||
@ -13,7 +13,7 @@ use uuid::Uuid;
|
||||
use crate::jobs::manager::{JobManager, JobOperation, JobStatus};
|
||||
use crate::packages::PackageManagerBackend;
|
||||
|
||||
use super::packages::{ApiResponse, ApiError, JobResponseData};
|
||||
use super::packages::{ApiError, ApiResponse, JobResponseData};
|
||||
|
||||
/// Patch list response data
|
||||
#[derive(Debug, Serialize)]
|
||||
@ -48,11 +48,11 @@ pub async fn list_patches(
|
||||
match backend.list_patches() {
|
||||
Ok(patches) => {
|
||||
let total = patches.len();
|
||||
let security_updates = patches.iter()
|
||||
let security_updates = patches
|
||||
.iter()
|
||||
.filter(|p| p.severity == "critical" || p.severity == "high")
|
||||
.count();
|
||||
let requires_reboot = patches.iter()
|
||||
.any(|p| p.name.contains("kernel"));
|
||||
let requires_reboot = patches.iter().any(|p| p.name.contains("kernel"));
|
||||
|
||||
let response = ApiResponse::success(PatchListData {
|
||||
patches,
|
||||
@ -96,7 +96,10 @@ pub async fn apply_patches(
|
||||
|
||||
// Create async job
|
||||
let package_list = body.packages.clone().unwrap_or_default();
|
||||
match job_manager.create_job(JobOperation::PatchApply, package_list).await {
|
||||
match job_manager
|
||||
.create_job(JobOperation::PatchApply, package_list)
|
||||
.await
|
||||
{
|
||||
Ok(job_id) => {
|
||||
// Spawn background task to execute the patching
|
||||
let backend_clone = backend.clone();
|
||||
@ -105,10 +108,19 @@ pub async fn apply_patches(
|
||||
|
||||
tokio::spawn(async move {
|
||||
let job_id_clone = job_id;
|
||||
|
||||
|
||||
// Update job to running
|
||||
let _ = job_manager_clone.update_job(&job_id_clone, JobStatus::Running, Some(0), Some("Starting patch application...".to_string())).await;
|
||||
let _ = job_manager_clone.add_job_log(&job_id_clone, "Job started".to_string()).await;
|
||||
let _ = job_manager_clone
|
||||
.update_job(
|
||||
&job_id_clone,
|
||||
JobStatus::Running,
|
||||
Some(0),
|
||||
Some("Starting patch application...".to_string()),
|
||||
)
|
||||
.await;
|
||||
let _ = job_manager_clone
|
||||
.add_job_log(&job_id_clone, "Job started".to_string())
|
||||
.await;
|
||||
|
||||
// Execute patching
|
||||
match backend_clone.apply_patches(request.packages.as_deref()) {
|
||||
@ -118,12 +130,22 @@ pub async fn apply_patches(
|
||||
|
||||
// Handle reboot if requested
|
||||
if request.reboot {
|
||||
let _ = job_manager_clone.add_job_log(&job_id_clone, format!("Reboot scheduled in {} seconds", request.reboot_delay_seconds)).await;
|
||||
let _ = job_manager_clone
|
||||
.add_job_log(
|
||||
&job_id_clone,
|
||||
format!(
|
||||
"Reboot scheduled in {} seconds",
|
||||
request.reboot_delay_seconds
|
||||
),
|
||||
)
|
||||
.await;
|
||||
// In production, would trigger actual reboot via system handler
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
let _ = job_manager_clone.fail_job(&job_id_clone, e.to_string()).await;
|
||||
let _ = job_manager_clone
|
||||
.fail_job(&job_id_clone, e.to_string())
|
||||
.await;
|
||||
error!(job_id = %job_id_clone, error = %e, "Patch application failed");
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,9 +11,9 @@ use serde::{Deserialize, Serialize};
|
||||
use tracing::{error, info, warn};
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::packages::{ApiResponse, JobResponseData};
|
||||
use crate::jobs::manager::{JobManager, JobOperation, JobStatus};
|
||||
use crate::packages::PackageManagerBackend;
|
||||
use super::packages::{ApiResponse, JobResponseData};
|
||||
|
||||
/// Normalize and validate file paths to prevent path traversal attacks (VULN-002)
|
||||
/// Returns None if path contains traversal patterns
|
||||
@ -22,7 +22,7 @@ fn normalize_path(path: &str) -> Option<String> {
|
||||
if path.contains("..") || path.contains("//") {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
||||
// Decode common URL-encoded traversal attempts
|
||||
let decoded = path
|
||||
.replace("%2e", ".")
|
||||
@ -31,12 +31,12 @@ fn normalize_path(path: &str) -> Option<String> {
|
||||
.replace("%2F", "/")
|
||||
.replace("%5c", "\\")
|
||||
.replace("%5C", "\\");
|
||||
|
||||
|
||||
// Check decoded path for traversal
|
||||
if decoded.contains("..") || decoded.contains("//") || decoded.contains("\\") {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
||||
// Ensure path starts with expected prefix or is relative
|
||||
Some(path.to_string())
|
||||
}
|
||||
@ -115,9 +115,7 @@ pub async fn get_system_info(
|
||||
}
|
||||
|
||||
/// Health check endpoint
|
||||
pub async fn health_check(
|
||||
_req: HttpRequest,
|
||||
) -> impl Responder {
|
||||
pub async fn health_check(_req: HttpRequest) -> impl Responder {
|
||||
let request_id = Uuid::new_v4().to_string();
|
||||
let timestamp = Utc::now().to_rfc3339();
|
||||
|
||||
@ -125,7 +123,9 @@ pub async fn health_check(
|
||||
let uptime_seconds = std::fs::read_to_string("/proc/uptime")
|
||||
.ok()
|
||||
.and_then(|content| {
|
||||
content.split_whitespace().next()
|
||||
content
|
||||
.split_whitespace()
|
||||
.next()
|
||||
.and_then(|s| s.parse::<f64>().ok())
|
||||
.map(|f| f as u64)
|
||||
})
|
||||
@ -186,20 +186,33 @@ pub async fn reboot_system(
|
||||
|
||||
tokio::spawn(async move {
|
||||
let job_id_clone = job_id;
|
||||
|
||||
|
||||
// Update job to running
|
||||
let _ = job_manager_clone.update_job(&job_id_clone, JobStatus::Running, Some(0), Some("Preparing system reboot...".to_string())).await;
|
||||
let _ = job_manager_clone.add_job_log(&job_id_clone, "Job started".to_string()).await;
|
||||
let _ = job_manager_clone
|
||||
.update_job(
|
||||
&job_id_clone,
|
||||
JobStatus::Running,
|
||||
Some(0),
|
||||
Some("Preparing system reboot...".to_string()),
|
||||
)
|
||||
.await;
|
||||
let _ = job_manager_clone
|
||||
.add_job_log(&job_id_clone, "Job started".to_string())
|
||||
.await;
|
||||
|
||||
// Execute reboot
|
||||
match backend_clone.reboot_system(delay_clone) {
|
||||
Ok(_) => {
|
||||
let _ = job_manager_clone.add_job_log(&job_id_clone, "Reboot command executed".to_string()).await;
|
||||
let _ = job_manager_clone
|
||||
.add_job_log(&job_id_clone, "Reboot command executed".to_string())
|
||||
.await;
|
||||
// Note: Job won't complete normally since system reboots
|
||||
info!(job_id = %job_id_clone, "System reboot initiated");
|
||||
}
|
||||
Err(e) => {
|
||||
let _ = job_manager_clone.fail_job(&job_id_clone, e.to_string()).await;
|
||||
let _ = job_manager_clone
|
||||
.fail_job(&job_id_clone, e.to_string())
|
||||
.await;
|
||||
error!(job_id = %job_id_clone, error = %e, "System reboot failed");
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,11 +6,11 @@
|
||||
//! Note: Full WebSocket implementation requires actix-web-actors compatibility.
|
||||
//! This stub provides the endpoint structure for future enhancement.
|
||||
|
||||
use actix_web::{web, HttpRequest, HttpResponse, Error, http::StatusCode};
|
||||
use actix_web::{http::StatusCode, web, Error, HttpRequest, HttpResponse};
|
||||
use chrono::Utc;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::info;
|
||||
use uuid::Uuid;
|
||||
use chrono::Utc;
|
||||
|
||||
use crate::jobs::manager::JobManager;
|
||||
|
||||
@ -24,9 +24,7 @@ pub enum WsClientMessage {
|
||||
job_id: Option<String>,
|
||||
},
|
||||
#[serde(rename = "unsubscribe")]
|
||||
Unsubscribe {
|
||||
job_id: String,
|
||||
},
|
||||
Unsubscribe { job_id: String },
|
||||
}
|
||||
|
||||
/// WebSocket message to client
|
||||
@ -72,7 +70,7 @@ pub async fn websocket_handler(
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let ws_id = Uuid::new_v4();
|
||||
info!(ws_id = %ws_id, "WebSocket connection request");
|
||||
|
||||
|
||||
// Check if this is a WebSocket upgrade request
|
||||
if req
|
||||
.headers()
|
||||
@ -84,7 +82,7 @@ pub async fn websocket_handler(
|
||||
// WebSocket upgrade requested
|
||||
// In full implementation, this would use actix-web-actors::ws::start()
|
||||
// For now, return a response indicating WebSocket support
|
||||
|
||||
|
||||
let response_msg = serde_json::json!({
|
||||
"event": "connected",
|
||||
"ws_id": ws_id.to_string(),
|
||||
@ -92,7 +90,7 @@ pub async fn websocket_handler(
|
||||
"message": "WebSocket endpoint ready. Full implementation requires actix-web-actors compatibility.",
|
||||
"polling_alternative": "Use GET /api/v1/jobs/{id} for job status polling"
|
||||
});
|
||||
|
||||
|
||||
// Return HTTP 101 Switching Protocols for WebSocket upgrade
|
||||
// In production, this would be handled by actix-web-actors
|
||||
Ok(HttpResponse::build(StatusCode::SWITCHING_PROTOCOLS)
|
||||
@ -113,7 +111,7 @@ pub async fn websocket_handler(
|
||||
},
|
||||
"alternative": "Use GET /api/v1/jobs/{id} for job status polling"
|
||||
});
|
||||
|
||||
|
||||
Ok(HttpResponse::Ok().json(info_msg))
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,10 +11,10 @@ pub mod handlers;
|
||||
pub mod routes;
|
||||
|
||||
// Re-export handlers for convenience
|
||||
pub use handlers::jobs;
|
||||
pub use handlers::packages;
|
||||
pub use handlers::patches;
|
||||
pub use handlers::system;
|
||||
pub use handlers::jobs;
|
||||
pub use handlers::websocket;
|
||||
|
||||
// Re-export routes configuration
|
||||
|
||||
@ -2,13 +2,13 @@
|
||||
//!
|
||||
//! Aggregates all endpoint routes and configures the Actix-web application.
|
||||
|
||||
use actix_web::{web, HttpResponse, http::Method};
|
||||
use actix_web::{http::Method, web, HttpResponse};
|
||||
use tracing::info;
|
||||
|
||||
use crate::packages::create_backend;
|
||||
use crate::jobs::manager::JobManager;
|
||||
use crate::packages::create_backend;
|
||||
|
||||
use super::handlers::{packages, patches, system, jobs, websocket};
|
||||
use super::handlers::{jobs, packages, patches, system, websocket};
|
||||
|
||||
/// Default service handler for unsupported HTTP methods (VULN-005)
|
||||
/// Returns 405 Method Not Allowed instead of 404 for known endpoints
|
||||
@ -25,23 +25,21 @@ pub fn configure_api_routes(
|
||||
) {
|
||||
info!("Configuring API v1 routes");
|
||||
|
||||
cfg.app_data(job_manager)
|
||||
.app_data(backend)
|
||||
.service(
|
||||
web::scope("/api/v1")
|
||||
// VULN-005: Default handler for unsupported methods returns 405 instead of 404
|
||||
.default_service(web::route().to(method_not_allowed))
|
||||
// Package Management Endpoints
|
||||
.configure(packages::configure_routes)
|
||||
// Patch Management Endpoints
|
||||
.configure(patches::configure_routes)
|
||||
// System Management Endpoints
|
||||
.configure(system::configure_routes)
|
||||
// Job Management Endpoints
|
||||
.configure(jobs::configure_routes)
|
||||
// WebSocket Endpoint
|
||||
.configure(websocket::configure_routes),
|
||||
);
|
||||
cfg.app_data(job_manager).app_data(backend).service(
|
||||
web::scope("/api/v1")
|
||||
// VULN-005: Default handler for unsupported methods returns 405 instead of 404
|
||||
.default_service(web::route().to(method_not_allowed))
|
||||
// Package Management Endpoints
|
||||
.configure(packages::configure_routes)
|
||||
// Patch Management Endpoints
|
||||
.configure(patches::configure_routes)
|
||||
// System Management Endpoints
|
||||
.configure(system::configure_routes)
|
||||
// Job Management Endpoints
|
||||
.configure(jobs::configure_routes)
|
||||
// WebSocket Endpoint
|
||||
.configure(websocket::configure_routes),
|
||||
);
|
||||
}
|
||||
|
||||
/// Health check route (outside API scope for load balancer checks)
|
||||
|
||||
Reference in New Issue
Block a user