mirror of
https://github.com/getnora-io/nora.git
synced 2026-04-12 10:20:32 +00:00
fix: code quality hardening — unwrap removal, unsafe forbid, Go/Raw tests (#72)
* fix: remove unwrap() from production code, improve error handling - Replace unwrap() with proper error handling in npm, mirror, validation - Add input validation to cargo registry (crate name + version) - Improve expect() messages with descriptive context in metrics, rate_limit - Remove unnecessary clone() in error.rs, docker.rs, npm.rs, dashboard_metrics - Add #![deny(clippy::unwrap_used)] to prevent future unwrap in prod code - Add let-else pattern for safer null checks in validation.rs * docs: update SECURITY.md — add 0.3.x to supported versions * security: forbid unsafe code at crate level Add #![forbid(unsafe_code)] to both lib.rs and main.rs. NORA has zero unsafe blocks — this prevents future additions without removing the forbid attribute (stronger than deny). * build: add rust-toolchain.toml, Dockerfile HEALTHCHECK - Pin toolchain to stable with clippy + rustfmt components - Add Docker HEALTHCHECK for standalone deployments (wget /health) * test: add Go proxy and Raw registry integration tests Go proxy tests: list, .info, .mod, @latest, path traversal, 404 Raw registry tests: upload/download, HEAD, 404, path traversal, overwrite, delete, binary data (10KB)
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
use crate::activity_log::{ActionType, ActivityEntry};
|
||||
use crate::audit::AuditEntry;
|
||||
use crate::validation::validate_storage_key;
|
||||
use crate::AppState;
|
||||
use axum::{
|
||||
extract::{Path, State},
|
||||
@@ -26,6 +27,10 @@ async fn get_metadata(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path(crate_name): Path<String>,
|
||||
) -> Response {
|
||||
// Validate input to prevent path traversal
|
||||
if validate_storage_key(&crate_name).is_err() {
|
||||
return StatusCode::BAD_REQUEST.into_response();
|
||||
}
|
||||
let key = format!("cargo/{}/metadata.json", crate_name);
|
||||
match state.storage.get(&key).await {
|
||||
Ok(data) => (StatusCode::OK, data).into_response(),
|
||||
@@ -37,6 +42,10 @@ async fn download(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path((crate_name, version)): Path<(String, String)>,
|
||||
) -> Response {
|
||||
// Validate inputs to prevent path traversal
|
||||
if validate_storage_key(&crate_name).is_err() || validate_storage_key(&version).is_err() {
|
||||
return StatusCode::BAD_REQUEST.into_response();
|
||||
}
|
||||
let key = format!(
|
||||
"cargo/{}/{}/{}-{}.crate",
|
||||
crate_name, version, crate_name, version
|
||||
|
||||
Reference in New Issue
Block a user