mirror of
https://github.com/DaLaw2/NetGuardia.git
synced 2026-08-24 14:10:28 +09:00
feat(audit): chain verify HTTP endpoint
GET /api/audit/verify walks the WORM hash chain and reports whether every row_hash still matches H(ts||actor||action||detail||prev_hash). Same verification the CLI --verify-audit-log flag runs, now reachable from the dashboard so auditors can check integrity without shell access. Response carries the broken row id in the error message when the chain fails. Route falls under the existing /api/audit/ prefix so AuthMiddleware already gates it behind the system:read permission — no middleware change needed. Uses Arc<dyn AuditRepo> following the fusion explain endpoint's DDD pattern rather than touching Database directly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
47d73cb07a
commit
8b0e5d479a
@ -1,10 +1,15 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix_web::{HttpResponse, Scope, web};
|
||||
|
||||
use crate::adapter::persistence::Database;
|
||||
use crate::core::auth::extractor::AuthClaims;
|
||||
use crate::interface::port::audit::AuditRepo;
|
||||
|
||||
pub fn initialize() -> Scope {
|
||||
web::scope("/audit").route("", web::get().to(list_audit_logs))
|
||||
web::scope("/audit")
|
||||
.route("", web::get().to(list_audit_logs))
|
||||
.route("/verify", web::get().to(verify_chain))
|
||||
}
|
||||
|
||||
async fn list_audit_logs(_auth: AuthClaims, db: web::Data<Database>) -> HttpResponse {
|
||||
@ -27,3 +32,23 @@ async fn list_audit_logs(_auth: AuthClaims, db: web::Data<Database>) -> HttpResp
|
||||
Err(_) => HttpResponse::Ok().json(serde_json::json!([])),
|
||||
}
|
||||
}
|
||||
|
||||
/// `GET /api/audit/verify` — walk the WORM hash chain and report whether
|
||||
/// every row_hash still matches `H(ts || actor || action || detail ||
|
||||
/// prev_hash)`. Surfaces over HTTP the same verification the CLI's
|
||||
/// `--verify-audit-log` flag performs, so auditors can check chain
|
||||
/// integrity without shell access. Any mismatch returns the offending
|
||||
/// row id inside `error` so the dashboard can link straight to it.
|
||||
async fn verify_chain(_auth: AuthClaims, audit: web::Data<Arc<dyn AuditRepo>>) -> HttpResponse {
|
||||
match audit.verify_audit_log_chain() {
|
||||
Ok(count) => HttpResponse::Ok().json(serde_json::json!({
|
||||
"chain_intact": true,
|
||||
"verified": count,
|
||||
})),
|
||||
Err(e) => HttpResponse::InternalServerError().json(serde_json::json!({
|
||||
"chain_intact": false,
|
||||
"verified": 0,
|
||||
"error": e.to_string(),
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user