use axum::Json;
use axum::extract::{Path, Query, State};
use serde::Deserialize;
use serde_json::Value;
use crate::admin;
use crate::webadmin::AdminState;
use crate::webadmin::error::AdminError;
use crate::webadmin::handlers::paging::{PageParams, page_envelope};
use crate::webadmin::handlers::params::{empty_is_absent, empty_is_absent_serial};
use crate::webadmin::session::Authenticated;
use acme_proxy_store::audit::AuditEntry;
use acme_proxy_store::audit::AuditQuery;
#[derive(Debug, Deserialize, Default)]
pub struct AuditListParams {
#[serde(default, deserialize_with = "empty_is_absent")]
pub profile: Option<String>,
#[serde(rename = "accountId", default, deserialize_with = "empty_is_absent")]
pub account_id: Option<String>,
#[serde(rename = "orderId", default, deserialize_with = "empty_is_absent")]
pub order_id: Option<String>,
#[serde(
rename = "certSerial",
default,
deserialize_with = "empty_is_absent_serial"
)]
pub cert_serial: Option<String>,
#[serde(default, deserialize_with = "empty_is_absent")]
pub event: Option<String>,
#[serde(default, deserialize_with = "empty_is_absent")]
pub outcome: Option<String>,
pub limit: Option<i64>,
pub offset: Option<i64>,
}
pub async fn list_audit(
State(state): State<AdminState>,
Query(params): Query<AuditListParams>,
_auth: Authenticated,
) -> Result<Json<Value>, AdminError> {
let page = PageParams::from(params.limit, params.offset).resolve(&state.config);
let query = AuditQuery {
profile: params.profile,
account_id: params.account_id,
order_id: params.order_id,
cert_serial: params.cert_serial,
event: params.event,
outcome: params.outcome,
since: None,
limit: page.limit,
offset: page.offset,
};
let (entries, total) = admin::list_audit(&query, state.database.clone()).await?;
let items = entries.iter().map(AuditEntry::to_json).collect();
Ok(Json(page_envelope(items, total, page)))
}
pub async fn get_audit(
State(state): State<AdminState>,
Path(id): Path<i64>,
_auth: Authenticated,
) -> Result<Json<Value>, AdminError> {
let entry = admin::find_audit(id, state.database.clone())
.await?
.ok_or_else(|| AdminError::not_found(format!("audit row {id} not found")))?;
Ok(Json(entry.to_json()))
}