diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 13ae708af..ef8ed35d1 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -19,7 +19,7 @@ inquire = "0.7.5" lazy_static = "1.4.0" ratatui = "0.29.0" regex = "1.10.3" -reqwest = { version = "0.12.9", features = ["json"] } +reqwest = { version = "0.12.9", features = ["json", "rustls-tls"] } rpassword = "7.3.1" serde = { version = "1.0.196", features = ["derive"] } serde_json = "1.0.113" @@ -28,6 +28,7 @@ thiserror = "2.0.3" tokio = { version = "1.36.0", features = ["full"] } uuid = { version = "1.7.0", features = ["v4", "serde"] } colored = "3.0" +rustls = { version = "0.22", features = ["tls12"] } [dev-dependencies] tempfile = "3.16.0" diff --git a/cli/src/utils/buster/api.rs b/cli/src/utils/buster/api.rs index fcd58a62c..e4941aaa2 100644 --- a/cli/src/utils/buster/api.rs +++ b/cli/src/utils/buster/api.rs @@ -3,6 +3,7 @@ use reqwest::{ header::{HeaderMap, HeaderValue}, Client, }; +use std::error::Error as StdError; use super::{ PostDataSourcesRequest, DeployDatasetsRequest, ValidateApiKeyRequest, ValidateApiKeyResponse, @@ -17,7 +18,10 @@ pub struct BusterClient { impl BusterClient { pub fn new(base_url: String, api_key: String) -> Result { - let client = Client::builder().build()?; + let client = Client::builder() + .use_rustls_tls() + .timeout(std::time::Duration::from_secs(30)) + .build()?; Ok(Self { client, @@ -36,29 +40,81 @@ impl BusterClient { } pub async fn validate_api_key(&self) -> Result { + println!("Debug: Starting API key validation"); let request = ValidateApiKeyRequest { api_key: self.api_key.clone(), }; + println!("Debug: Created request object"); - let response = self + let mut headers = HeaderMap::new(); + headers.insert( + reqwest::header::CONTENT_TYPE, + HeaderValue::from_static("application/json"), + ); + headers.insert( + reqwest::header::ACCEPT, + HeaderValue::from_static("*/*"), + ); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static("buster-cli"), + ); + println!("Debug: Set up headers: {:?}", headers); + + let url = format!("{}/api/v1/api_keys/validate", self.base_url); + println!("Debug: Making request to URL: {}", url); + + let request = self .client - .post(format!("{}/api/v1/api_keys/validate", self.base_url)) - .json(&request) - .send() - .await?; + .post(&url) + .headers(headers) + .json(&request); + println!("Debug: Built request: {:?}", request); + + let response = match request.send().await { + Ok(resp) => resp, + Err(e) => { + println!("Debug: Request failed with error: {:?}", e); + if let Some(source) = e.source() { + println!("Debug: Error source: {:?}", source); + } + if e.is_timeout() { + println!("Debug: Error was a timeout"); + } + if e.is_connect() { + println!("Debug: Error was a connection error"); + } + if e.is_request() { + println!("Debug: Error was a request error"); + } + return Err(anyhow::anyhow!("Request failed: {}", e)); + } + }; + println!("Debug: Got response: {:?}", response); if !response.status().is_success() { + let status = response.status(); + let text = response.text().await?; + println!("Debug: Error response - Status: {}, Body: {}", status, text); return Err(anyhow::anyhow!( - "Failed to validate API key. This could be due to an invalid URL" + "Failed to validate API key. Status: {}, Response: {}", + status, + text )); } match response.json::().await { - Ok(validate_response) => Ok(validate_response.valid), - Err(e) => Err(anyhow::anyhow!( - "Failed to parse validate API key response: {}", - e - )), + Ok(validate_response) => { + println!("Debug: Successfully parsed response: {:?}", validate_response); + Ok(validate_response.valid) + } + Err(e) => { + println!("Debug: Failed to parse response: {:?}", e); + Err(anyhow::anyhow!( + "Failed to parse validate API key response: {}", + e + )) + } } }