vta_cli_common/commands/
step_up.rs1use serde_json::Value;
8use vta_sdk::prelude::*;
9
10pub async fn cmd_policy_show(client: &VtaClient) -> Result<(), Box<dyn std::error::Error>> {
12 let policy = client.get_step_up_policy().await?;
13 print_policy(&policy);
14 Ok(())
15}
16
17pub async fn cmd_policy_set(
20 client: &VtaClient,
21 policy: Value,
22) -> Result<(), Box<dyn std::error::Error>> {
23 let effective = client.set_step_up_policy(policy).await?;
24 println!("Step-up policy updated:");
25 print_policy(&effective);
26 Ok(())
27}
28
29pub async fn cmd_policy_disable(client: &VtaClient) -> Result<(), Box<dyn std::error::Error>> {
31 let effective = client
32 .set_step_up_policy(serde_json::json!({ "enabled": false, "floors": [] }))
33 .await?;
34 println!("Step-up policy disabled (AAL1 everywhere):");
35 print_policy(&effective);
36 Ok(())
37}
38
39pub fn print_policy(p: &Value) {
41 let enabled = p.get("enabled").and_then(Value::as_bool).unwrap_or(false);
42 println!(
43 " Enforcement: {}",
44 if enabled {
45 "ENABLED"
46 } else {
47 "disabled (AAL1 everywhere)"
48 }
49 );
50 let floors = p.get("floors").and_then(Value::as_array);
51 match floors {
52 Some(floors) if !floors.is_empty() => {
53 println!(" Floors:");
54 for f in floors {
55 let op = f.get("operation").and_then(Value::as_str).unwrap_or("?");
56 let mode = f.get("mode").and_then(Value::as_str).unwrap_or("?");
57 let carve = f
58 .get("allowAal1IfNonEscalating")
59 .and_then(Value::as_bool)
60 .unwrap_or(false);
61 let suffix = if carve {
62 " (AAL1 carve-out for non-escalating self-service)"
63 } else {
64 ""
65 };
66 println!(" {op:<18} → {mode}{suffix}");
67 }
68 }
69 _ => println!(" Floors: (none)"),
70 }
71}