use super::helpers::TrustTaskOutcome;
use serde_json::Value;
use trust_tasks_rs::TrustTask;
use crate::auth::AuthClaims;
use crate::server::AppState;
use super::helpers::{parse_payload, success_response};
pub(super) async fn handle_trust_task_discovery(
_state: &AppState,
_auth: &AuthClaims,
doc: TrustTask<Value>,
) -> TrustTaskOutcome {
use trust_tasks_rs::specs::trust_task_discovery::v0_1 as wire;
let req: wire::Payload = match parse_payload(&doc) {
Ok(r) => r,
Err(resp) => return resp,
};
let patterns: Vec<String> = req.patterns.iter().map(|p| p.to_string()).collect();
let mut matched: Vec<String> = super::dispatched_uris()
.into_iter()
.filter(|uri| slug_matches_any(uri, &patterns))
.map(str::to_string)
.collect();
matched.sort_unstable();
matched.dedup();
let body = serde_json::json!({
"frameworkVersion": FRAMEWORK_VERSION,
"supportedTypes": matched,
});
success_response(&doc, body)
}
const FRAMEWORK_VERSION: &str = "0.2";
fn slug_matches_any(uri: &str, patterns: &[String]) -> bool {
if patterns.is_empty() {
return true;
}
let slug = slug_of(uri);
patterns
.iter()
.any(|p| trust_tasks_rs::discovery::match_slug(p, slug))
}
fn slug_of(uri: &str) -> &str {
uri.strip_prefix("https://trusttasks.org/spec/")
.unwrap_or(uri)
}
#[cfg(test)]
mod tests {
use super::*;
fn pats(p: &[&str]) -> Vec<String> {
p.iter().map(|s| s.to_string()).collect()
}
#[test]
fn patterns_match_the_slug_not_the_whole_uri() {
let grant = "https://trusttasks.org/spec/acl/grant/0.1";
assert!(slug_matches_any(grant, &pats(&["acl/*"])));
assert!(slug_matches_any(grant, &pats(&["acl/grant/0.1"])));
assert!(!slug_matches_any(grant, &pats(&["vta/acl/*"])));
assert!(!slug_matches_any(grant, &pats(&["keys/*"])));
}
#[test]
fn no_patterns_means_everything() {
let uri = "https://trusttasks.org/spec/acl/grant/0.1";
assert!(slug_matches_any(uri, &[]));
assert!(slug_matches_any(uri, &pats(&["*"])));
}
#[test]
fn interior_wildcards_are_not_globs() {
let uri = "https://trusttasks.org/spec/acl/grant/0.1";
assert!(!slug_matches_any(uri, &pats(&["*/grant/0.1"])));
}
#[test]
fn a_prefixless_uri_is_returned_whole() {
assert_eq!(slug_of("urn:example:odd"), "urn:example:odd");
assert!(slug_matches_any(
"urn:example:odd",
&pats(&["urn:example:odd"])
));
}
#[test]
fn discovery_draws_on_the_real_dispatch_table() {
let all = crate::trust_tasks::dispatched_uris();
assert!(
all.len() > 50,
"only {} dispatched URIs — discovery would under-report; fix the \
table rather than this floor",
all.len()
);
assert!(
all.contains(&vta_sdk::trust_tasks::TASK_TRUST_TASK_DISCOVERY_0_1),
"discovery must advertise itself — a client that cannot see it \
cannot know to ask again"
);
}
}