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:
2026-03-31 21:15:59 +03:00
committed by GitHub
parent 9ec5fe526b
commit bb125db074
16 changed files with 186 additions and 26 deletions

View File

@@ -26,7 +26,7 @@ lazy_static! {
"nora_http_requests_total",
"Total number of HTTP requests",
&["registry", "method", "status"]
).expect("metric can be created");
).expect("failed to create HTTP_REQUESTS_TOTAL metric at startup");
/// HTTP request duration histogram
pub static ref HTTP_REQUEST_DURATION: HistogramVec = register_histogram_vec!(
@@ -34,28 +34,28 @@ lazy_static! {
"HTTP request latency in seconds",
&["registry", "method"],
vec![0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0]
).expect("metric can be created");
).expect("failed to create HTTP_REQUEST_DURATION metric at startup");
/// Cache requests counter (hit/miss)
pub static ref CACHE_REQUESTS: IntCounterVec = register_int_counter_vec!(
"nora_cache_requests_total",
"Total cache requests",
&["registry", "result"]
).expect("metric can be created");
).expect("failed to create CACHE_REQUESTS metric at startup");
/// Storage operations counter
pub static ref STORAGE_OPERATIONS: IntCounterVec = register_int_counter_vec!(
"nora_storage_operations_total",
"Total storage operations",
&["operation", "status"]
).expect("metric can be created");
).expect("failed to create STORAGE_OPERATIONS metric at startup");
/// Artifacts count by registry
pub static ref ARTIFACTS_TOTAL: IntCounterVec = register_int_counter_vec!(
"nora_artifacts_total",
"Total artifacts stored",
&["registry"]
).expect("metric can be created");
).expect("failed to create ARTIFACTS_TOTAL metric at startup");
}
/// Routes for metrics endpoint