auth dns over atproto
at main 93 lines 2.7 kB view raw
1use anyhow::{Context, Result}; 2use serde::{Deserialize, Serialize}; 3 4/// HTTP client for communicating with the onis appview API. 5#[derive(Clone)] 6pub struct AppviewClient { 7 /// Underlying HTTP client. 8 client: reqwest::Client, 9 /// Base URL of the appview, e.g. `"http://localhost:3000"`. 10 base_url: String, 11} 12 13/// A zone that is due for re-verification, returned by the appview stale zones endpoint. 14#[derive(Debug, Deserialize)] 15pub struct StaleZoneEntry { 16 /// Domain name of the zone. 17 pub zone: String, 18 /// DID of the zone owner. 19 pub did: String, 20 /// Current verification status. 21 pub verified: bool, 22 /// Unix timestamp when the zone was first seen. 23 pub first_seen: i64, 24 /// Unix timestamp of the last successful verification, if any. 25 pub last_verified: Option<i64>, 26} 27 28/// Wire format for the `GET /v1/zones/stale` response. 29#[derive(Debug, Deserialize)] 30struct StaleZonesResponse { 31 /// List of zones needing re-verification. 32 zones: Vec<StaleZoneEntry>, 33} 34 35/// Request body for `PUT /v1/verification`. 36#[derive(Serialize)] 37struct VerificationBody { 38 /// Domain name of the zone. 39 zone: String, 40 /// DID of the zone owner. 41 did: String, 42 /// Whether the zone passed delegation verification. 43 verified: bool, 44} 45 46impl AppviewClient { 47 pub fn new(base_url: String) -> Self { 48 Self { 49 client: reqwest::Client::new(), 50 base_url, 51 } 52 } 53 54 pub async fn get_stale_zones(&self, checked_before: i64) -> Result<Vec<StaleZoneEntry>> { 55 let url = format!( 56 "{}/v1/zones/stale?checked_before={}", 57 self.base_url, checked_before 58 ); 59 60 let body: StaleZonesResponse = self 61 .client 62 .get(&url) 63 .send() 64 .await 65 .context("failed to fetch stale zones")? 66 .error_for_status() 67 .context("stale zones request failed")? 68 .json() 69 .await 70 .context("failed to deserialize stale zones response")?; 71 72 Ok(body.zones) 73 } 74 75 pub async fn set_verification(&self, zone: &str, did: &str, verified: bool) -> Result<()> { 76 let url = format!("{}/v1/verification", self.base_url); 77 78 self.client 79 .put(&url) 80 .json(&VerificationBody { 81 zone: zone.to_string(), 82 did: did.to_string(), 83 verified, 84 }) 85 .send() 86 .await 87 .context("failed to set verification")? 88 .error_for_status() 89 .with_context(|| format!("set verification for {zone} failed"))?; 90 91 Ok(()) 92 } 93}