use super::helpers::TrustTaskOutcome;
use serde_json::Value;
use trust_tasks_rs::TrustTask;
use vta_sdk::protocols::backup_management::descriptors::{
AbortBundleBody, CompleteExportBody, FinalizeImportBody, InitiateExportBody, InitiateImportBody,
};
use crate::auth::AuthClaims;
use crate::operations::backup::descriptors;
use crate::server::AppState;
use super::helpers::{TRANSPORT_TRUST_TASK, app_error_to_reject, parse_payload, success_response};
async fn record_bundle_event(
state: &AppState,
auth: &AuthClaims,
action: &str,
bundle_id: &str,
detail: String,
) {
if let Err(e) = crate::audit::record_with_detail(
&state.audit_sink,
action,
&auth.did,
Some(bundle_id),
"success",
Some(TRANSPORT_TRUST_TASK),
None,
Some(&detail),
)
.await
{
tracing::warn!(error = %e, action, "audit record failed for {action}");
}
}
pub(super) async fn handle_initiate_export(
state: &AppState,
auth: &AuthClaims,
doc: TrustTask<Value>,
) -> TrustTaskOutcome {
let req: InitiateExportBody = match parse_payload(&doc) {
Ok(r) => r,
Err(resp) => return resp,
};
let deps = crate::operations::descriptor_deps_from_app_state(state);
let include_audit = req.include_audit;
match descriptors::initiate_export(&deps, auth, req).await {
Ok(body) => {
record_bundle_event(
state,
auth,
"backup.initiate-export",
&body.descriptor.bundle_id,
format!(
"includeAudit={include_audit} bytes={} expires={}",
body.descriptor.expected_size_bytes, body.descriptor.expires_at
),
)
.await;
success_response(&doc, body)
}
Err(e) => app_error_to_reject(&doc, e),
}
}
pub(super) async fn handle_complete_export(
state: &AppState,
auth: &AuthClaims,
doc: TrustTask<Value>,
) -> TrustTaskOutcome {
let req: CompleteExportBody = match parse_payload(&doc) {
Ok(r) => r,
Err(resp) => return resp,
};
let deps = crate::operations::descriptor_deps_from_app_state(state);
match descriptors::complete_export(&deps, auth, req).await {
Ok(body) => {
record_bundle_event(
state,
auth,
"backup.complete-export",
&body.bundle_id,
format!("downloaded={}", body.downloaded),
)
.await;
success_response(&doc, body)
}
Err(e) => app_error_to_reject(&doc, e),
}
}
pub(super) async fn handle_initiate_import(
state: &AppState,
auth: &AuthClaims,
doc: TrustTask<Value>,
) -> TrustTaskOutcome {
let req: InitiateImportBody = match parse_payload(&doc) {
Ok(r) => r,
Err(resp) => return resp,
};
let deps = crate::operations::descriptor_deps_from_app_state(state);
match descriptors::initiate_import(&deps, auth, req).await {
Ok(body) => {
record_bundle_event(
state,
auth,
"backup.initiate-import",
&body.descriptor.bundle_id,
format!(
"sha256={} bytes={} expires={}",
body.descriptor.expected_sha256,
body.descriptor.expected_size_bytes,
body.descriptor.expires_at
),
)
.await;
success_response(&doc, body)
}
Err(e) => app_error_to_reject(&doc, e),
}
}
pub(super) async fn handle_finalize_import(
state: &AppState,
auth: &AuthClaims,
doc: TrustTask<Value>,
) -> TrustTaskOutcome {
let req: FinalizeImportBody = match parse_payload(&doc) {
Ok(r) => r,
Err(resp) => return resp,
};
let deps = crate::operations::descriptor_deps_from_app_state(state);
match descriptors::finalize_import(&deps, auth, req).await {
Ok(body) => {
record_bundle_event(
state,
auth,
"backup.finalize-import",
&body.bundle_id,
format!(
"status={} source={} keys={} acls={} contexts={}",
body.status,
body.source_did.as_deref().unwrap_or("unknown"),
body.key_count,
body.acl_count,
body.context_count
),
)
.await;
success_response(&doc, body)
}
Err(e) => app_error_to_reject(&doc, e),
}
}
pub(super) async fn handle_abort(
state: &AppState,
auth: &AuthClaims,
doc: TrustTask<Value>,
) -> TrustTaskOutcome {
let req: AbortBundleBody = match parse_payload(&doc) {
Ok(r) => r,
Err(resp) => return resp,
};
let deps = crate::operations::descriptor_deps_from_app_state(state);
match descriptors::abort_bundle(&deps, auth, req).await {
Ok(body) => {
record_bundle_event(
state,
auth,
"backup.abort",
&body.bundle_id,
format!("aborted={}", body.aborted),
)
.await;
success_response(&doc, body)
}
Err(e) => app_error_to_reject(&doc, e),
}
}