use crate::types::error::{ErrorCode, HstpError};
#[allow(dead_code)]
#[derive(Debug)]
pub struct TokenResponse {
pub access_token: String,
}
#[allow(dead_code)]
pub async fn retrieve_auth_token_client_credentials(
client_id: String,
client_secret: String,
token_url: String,
audience: Option<String>,
scope: Option<String>,
) -> Result<TokenResponse, HstpError> {
use base64::{
alphabet,
engine::{GeneralPurpose, GeneralPurposeConfig},
Engine,
};
let encoded_client_id = urlencoding::encode(&client_id);
let encoded_client_secret = urlencoding::encode(&client_secret);
let header = format!("{}:{}", encoded_client_id, encoded_client_secret);
let header_ascii_bytes = header.as_bytes();
let encoded_header = GeneralPurpose::new(&alphabet::STANDARD, GeneralPurposeConfig::default())
.encode(header_ascii_bytes);
let mut headers = reqwest::header::HeaderMap::new();
headers.insert(
reqwest::header::AUTHORIZATION,
reqwest::header::HeaderValue::from_str(&format!("Basic {}", encoded_header))
.map_err(HstpError::from_error)?,
);
headers.insert(
reqwest::header::CONTENT_TYPE,
reqwest::header::HeaderValue::from_static("application/x-www-form-urlencoded"),
);
let body = "grant_type=client_credentials".to_string();
let body = if let Some(audience) = &audience {
format!("{}&audience={}", body, audience)
} else {
body
};
let body = if let Some(scope) = &scope {
format!("{}&scope={}", body, scope)
} else {
body
};
let client = reqwest::Client::new();
let response = client
.post(token_url.to_string())
.headers(headers)
.body(body)
.send()
.await
.map_err(HstpError::from_error)?;
if response.status().is_success() {
let response_body = response.text().await.map_err(HstpError::from_error)?;
let response_body: serde_json::Value = serde_json::from_str(&response_body)?;
let access_token = response_body["access_token"].as_str().ok_or_else(|| {
HstpError::new(
ErrorCode::None,
"Failed to retrieve access token".to_string(),
"".into(),
)
})?;
Ok(TokenResponse {
access_token: access_token.to_string(),
})
} else {
let status = response.status().to_string(); let error_body = response.text().await.unwrap_or_else(|_| "".to_string());
Err(HstpError::new(
ErrorCode::UnhandledError,
format!("Error response from server: {}", error_body),
status,
))
}
}