cloud_api_client.rs

 1use std::sync::Arc;
 2
 3use anyhow::{Result, anyhow};
 4pub use cloud_api_types::*;
 5use futures::AsyncReadExt as _;
 6use http_client::{AsyncBody, HttpClientWithUrl, Method, Request};
 7use parking_lot::RwLock;
 8
 9struct Credentials {
10    user_id: u32,
11    access_token: String,
12}
13
14pub struct CloudApiClient {
15    credentials: RwLock<Option<Credentials>>,
16    http_client: Arc<HttpClientWithUrl>,
17}
18
19impl CloudApiClient {
20    pub fn new(http_client: Arc<HttpClientWithUrl>) -> Self {
21        Self {
22            credentials: RwLock::new(None),
23            http_client,
24        }
25    }
26
27    pub fn has_credentials(&self) -> bool {
28        self.credentials.read().is_some()
29    }
30
31    pub fn set_credentials(&self, user_id: u32, access_token: String) {
32        *self.credentials.write() = Some(Credentials {
33            user_id,
34            access_token,
35        });
36    }
37
38    pub fn clear_credentials(&self) {
39        *self.credentials.write() = None;
40    }
41
42    fn authorization_header(&self) -> Result<String> {
43        let guard = self.credentials.read();
44        let credentials = guard
45            .as_ref()
46            .ok_or_else(|| anyhow!("No credentials provided"))?;
47
48        Ok(format!(
49            "{} {}",
50            credentials.user_id, credentials.access_token
51        ))
52    }
53
54    pub async fn get_authenticated_user(&self) -> Result<GetAuthenticatedUserResponse> {
55        let request = Request::builder()
56            .method(Method::GET)
57            .uri(
58                self.http_client
59                    .build_zed_cloud_url("/client/users/me", &[])?
60                    .as_ref(),
61            )
62            .header("Content-Type", "application/json")
63            .header("Authorization", self.authorization_header()?)
64            .body(AsyncBody::default())?;
65
66        let mut response = self.http_client.send(request).await?;
67
68        if !response.status().is_success() {
69            let mut body = String::new();
70            response.body_mut().read_to_string(&mut body).await?;
71
72            anyhow::bail!(
73                "Failed to get authenticated user.\nStatus: {:?}\nBody: {body}",
74                response.status()
75            )
76        }
77
78        let mut body = String::new();
79        response.body_mut().read_to_string(&mut body).await?;
80
81        Ok(serde_json::from_str(&body)?)
82    }
83}