mod login_response;
use azure_core::{
content_type,
error::{ErrorKind, ResultExt},
headers, HttpClient, Request, Url,
};
use azure_core::{from_json, Method};
use login_response::LoginResponse;
use std::sync::Arc;
use url::form_urlencoded;
pub async fn perform(
http_client: Arc<dyn HttpClient>,
client_id: &str,
client_secret: &str,
scopes: &[&str],
tenant_id: &str,
) -> azure_core::Result<LoginResponse> {
let encoded: String = form_urlencoded::Serializer::new(String::new())
.append_pair("client_id", client_id)
.append_pair("scope", &scopes.join(" "))
.append_pair("client_secret", client_secret)
.append_pair("grant_type", "client_credentials")
.finish();
let url = Url::parse(&format!(
"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"
))
.with_context(ErrorKind::DataConversion, || {
format!("The supplied tenant id could not be url encoded: {tenant_id}")
})?;
let mut req = Request::new(url, Method::Post);
req.insert_header(
headers::CONTENT_TYPE,
content_type::APPLICATION_X_WWW_FORM_URLENCODED,
);
req.set_body(encoded);
let rsp = http_client.execute_request(&req).await?;
let (rsp_status, rsp_headers, rsp_body) = rsp.deconstruct();
let rsp_body = rsp_body.collect().await?;
if !rsp_status.is_success() {
return Err(
ErrorKind::http_response_from_parts(rsp_status, &rsp_headers, &rsp_body).into_error(),
);
}
from_json(&rsp_body)
}