use super::private::{AsyncAuthFlow, AuthFlow};
use crate::{
RestError,
api::{ApiError, FormParams},
model::Token,
};
use base64::{Engine as _, engine::general_purpose};
use reqwest::blocking::Client;
pub struct ClientCredentials {
client_id: String,
client_secret: String,
}
impl AuthFlow for ClientCredentials {}
impl AsyncAuthFlow for ClientCredentials {}
impl ClientCredentials {
pub fn new(client_id: impl Into<String>, client_secret: impl Into<String>) -> Self {
Self {
client_id: client_id.into(),
client_secret: client_secret.into(),
}
}
pub fn request_token(&self, client: &Client) -> Result<Token, ApiError<RestError>> {
let (auth, params) = self.auth_value_and_params();
super::request_token(client, Some(auth), params)
}
pub async fn request_token_async(
&self,
client: &reqwest::Client,
) -> Result<Token, ApiError<RestError>> {
let (auth, params) = self.auth_value_and_params();
super::request_token_async(client, Some(auth), params).await
}
fn auth_value_and_params(&self) -> (String, FormParams<'_>) {
let credentials = format!("{}:{}", self.client_id, self.client_secret);
let mut auth = general_purpose::URL_SAFE_NO_PAD.encode(credentials);
auth.insert_str(0, "Basic ");
let mut params = FormParams::default();
params.push("grant_type", &"client_credentials");
(auth, params)
}
}