use crate::client::{multipart_part, run_task, API_BASE};
use anyhow::{Context, Result};
use reqwest::blocking::Client;
use reqwest::header::CONTENT_TYPE;
pub struct Card {
pub serial: String,
pub certificate_pem: Vec<u8>,
}
pub fn fetch(client: &Client, token: &str) -> Result<Card> {
let resp = run_task(
client,
token,
client
.post(format!("{API_BASE}/card/v1/cards/tasks"))
.bearer_auth(token)
.header(CONTENT_TYPE, "application/json"),
)
.context("listing cards")?
.1;
let text = String::from_utf8_lossy(&resp).to_string();
let cards: serde_json::Value =
serde_json::from_str(&text).with_context(|| format!("card list was not JSON: {text}"))?;
let serial = cards
.as_array()
.and_then(|a| a.first())
.and_then(|c| c.get("cardno"))
.and_then(|v| v.as_str())
.with_context(|| {
let snippet: String = text.chars().take(400).collect();
format!("no card / cardno in the card list; response was: {snippet}")
})?
.to_string();
let resp = run_task(
client,
token,
client
.post(format!(
"{API_BASE}/card/v1/cards/{serial}/certificates/tasks"
))
.bearer_auth(token)
.header(CONTENT_TYPE, "application/json"),
)
.context("fetching certificate")?
.1;
let certificate_pem = multipart_part(&resp, "certificate").context("extracting certificate")?;
Ok(Card {
serial,
certificate_pem,
})
}