use tracing::info;
use crate::messaging::auth::auth_for_trust_task_envelope;
use crate::server::AppState;
pub async fn dispatch_one(app_state: &AppState, payload: &[u8], sender_vid: &str) -> Vec<u8> {
app_state.tsp_reach.record(sender_vid);
tracing::debug!(sender = %sender_vid, "recorded TSP reachability (learn-from-inbound)");
let outcome = match auth_for_trust_task_envelope(app_state, sender_vid, payload).await {
Ok(auth) => {
crate::trust_tasks::dispatch_trust_task_core(
app_state,
&auth,
payload,
crate::trust_tasks::transport::TransportConfidentiality::EndToEnd,
)
.await
}
Err(e) => crate::trust_tasks::reject_trust_task(
payload,
trust_tasks_rs::RejectReason::PermissionDenied {
reason: e.to_string(),
},
),
};
info!(
sender = %sender_vid,
status = %outcome.status,
"TSP trust-task dispatched"
);
outcome.body
}
#[cfg(test)]
mod tests {
use super::*;
use crate::acl::{AclEntry, Role, store_acl_entry};
use crate::test_support::build_signing_test_app_state;
#[tokio::test]
async fn dispatch_one_unknown_sender_replies_with_error_envelope() {
let (app_state, _dir) = build_signing_test_app_state().await;
let body = dispatch_one(&app_state, b"{}", "did:key:zUnauthorizedTspSender").await;
assert!(
!body.is_empty(),
"unauthorized sender must get a reply envelope"
);
let doc: serde_json::Value = serde_json::from_slice(&body).expect("reply is JSON");
assert!(
doc.get("type").is_some() && doc.get("payload").is_some(),
"reply should be a trust-task error envelope, got: {doc}"
);
}
#[tokio::test]
async fn dispatch_one_authorized_sender_returns_reply_envelope() {
let (app_state, _dir) = build_signing_test_app_state().await;
let did = "did:key:zAuthorizedTspSender";
store_acl_entry(&app_state.acl_ks, &AclEntry::new(did, Role::Admin, "test"))
.await
.unwrap();
let body = dispatch_one(&app_state, b"{}", did).await;
assert!(
!body.is_empty(),
"authorized sender must get a reply envelope"
);
serde_json::from_slice::<serde_json::Value>(&body).expect("reply is JSON");
}
#[tokio::test]
async fn dispatch_one_records_sender_as_tsp_reachable() {
let (app_state, _dir) = build_signing_test_app_state().await;
let did = "did:key:zTspDevice";
assert!(
!app_state.tsp_reach.fresh(did),
"a DID we've never seen over TSP is not reachable"
);
let _ = dispatch_one(&app_state, b"{}", did).await;
assert!(
app_state.tsp_reach.fresh(did),
"an inbound TSP frame must mark its proven sender TSP-reachable"
);
}
}