auths_infra_http/
github_gist.rs1use std::future::Future;
4
5use serde::Deserialize;
6
7use auths_core::ports::platform::{PlatformError, PlatformProofPublisher};
8
9use crate::default_http_client;
10use crate::error::map_reqwest_error;
11
12#[derive(Deserialize)]
13struct GistResponse {
14 html_url: String,
15}
16
17pub struct HttpGistPublisher {
28 client: reqwest::Client,
29}
30
31impl HttpGistPublisher {
32 pub fn new() -> Self {
34 Self {
35 client: default_http_client(),
36 }
37 }
38}
39
40impl Default for HttpGistPublisher {
41 fn default() -> Self {
42 Self::new()
43 }
44}
45
46impl PlatformProofPublisher for HttpGistPublisher {
47 fn publish_proof(
48 &self,
49 access_token: &str,
50 claim_json: &str,
51 ) -> impl Future<Output = Result<String, PlatformError>> + Send {
52 let client = self.client.clone();
53 let access_token = access_token.to_string();
54 let claim_json = claim_json.to_string();
55 async move {
56 let payload = serde_json::json!({
57 "description": "Auths Identity Proof — cryptographic link between DID and GitHub account",
58 "public": true,
59 "files": {
60 "auths-proof.json": {
61 "content": claim_json
62 }
63 }
64 });
65
66 let resp = client
67 .post("https://api.github.com/gists")
68 .header("Authorization", format!("Bearer {access_token}"))
69 .header("User-Agent", "auths-cli")
70 .header("Accept", "application/vnd.github+json")
71 .json(&payload)
72 .send()
73 .await
74 .map_err(|e| PlatformError::Network(map_reqwest_error(e, "api.github.com")))?;
75
76 if !resp.status().is_success() {
77 let status = resp.status().as_u16();
78 let body = resp.text().await.unwrap_or_default();
79 return Err(PlatformError::Platform {
80 message: format!("GitHub Gist creation failed (HTTP {status}): {body}"),
81 });
82 }
83
84 let gist: GistResponse = resp.json().await.map_err(|e| PlatformError::Platform {
85 message: format!("failed to parse Gist response: {e}"),
86 })?;
87
88 Ok(gist.html_url)
89 }
90 }
91}