use super::consts::GRAFBASE_ACCESS_TOKEN_ENV_VAR;
use super::types::Credentials;
use super::{consts::CREDENTIALS_FILE, errors::ApiError};
use crate::consts::USER_AGENT;
use axum::http::{HeaderMap, HeaderValue};
use common::environment::get_user_dot_grafbase_path;
use reqwest::{header, Client};
use std::env;
use tokio::fs::read_to_string;
#[allow(clippy::module_name_repetitions)]
pub async fn create_client() -> Result<reqwest::Client, ApiError> {
let token = get_access_token().await?;
let mut headers = HeaderMap::new();
let mut bearer_token =
HeaderValue::from_str(&format!("Bearer {token}")).map_err(|_| ApiError::CorruptAccessToken)?;
bearer_token.set_sensitive(true);
headers.insert(header::AUTHORIZATION, bearer_token);
let mut user_agent = HeaderValue::from_str(USER_AGENT).expect("must be visible ascii");
user_agent.set_sensitive(true);
headers.insert(header::USER_AGENT, user_agent);
Ok(Client::builder()
.default_headers(headers)
.build()
.expect("TLS is supported in all targets"))
}
async fn get_access_token() -> Result<String, ApiError> {
match get_access_token_from_file().await {
Ok(token) => Ok(token),
Err(error) => env::var(GRAFBASE_ACCESS_TOKEN_ENV_VAR).map_err(|_| error),
}
}
async fn get_access_token_from_file() -> Result<String, ApiError> {
let user_dot_grafbase_path = get_user_dot_grafbase_path().ok_or(ApiError::FindUserDotGrafbaseFolder)?;
match user_dot_grafbase_path.try_exists() {
Ok(true) => {}
Ok(false) => return Err(ApiError::NotLoggedIn),
Err(error) => return Err(ApiError::ReadUserDotGrafbaseFolder(error)),
}
let credentials_file_path = user_dot_grafbase_path.join(CREDENTIALS_FILE);
match credentials_file_path.try_exists() {
Ok(true) => {}
Ok(false) => return Err(ApiError::NotLoggedIn),
Err(error) => return Err(ApiError::ReadCredentialsFile(error)),
}
let credential_file = read_to_string(user_dot_grafbase_path.join(CREDENTIALS_FILE))
.await
.map_err(ApiError::ReadCredentialsFile)?;
let credentials: Credentials<'_> =
serde_json::from_str(&credential_file).map_err(|_| ApiError::CorruptCredentialsFile)?;
Ok(credentials.access_token.to_owned())
}