use crate::{auth::openid::TokenConfig, reqwest::ClientFactory};
use async_trait::async_trait;
use drogue_client::openid::TokenProvider;
use url::Url;
#[derive(Clone, Debug, serde::Deserialize)]
pub struct ClientConfig {
pub url: Url,
#[serde(flatten, default)]
pub token_config: Option<TokenConfig>,
}
impl ClientConfig {
pub async fn into_client<T>(self) -> anyhow::Result<T>
where
T: ClientCreator,
{
let token = if let Some(token) = self.token_config {
Some(token.discover_from().await?)
} else {
None
};
T::new(ClientFactory::new().build()?, self.url, token)
}
}
#[async_trait]
pub trait ClientCreator: Sized {
fn new<TP>(client: reqwest::Client, url: Url, token_provider: TP) -> anyhow::Result<Self>
where
TP: TokenProvider + 'static;
}
impl ClientCreator for drogue_client::user::v1::Client {
fn new<TP>(client: reqwest::Client, url: Url, token_provider: TP) -> anyhow::Result<Self>
where
TP: TokenProvider + 'static,
{
let authn_url = url.join("/api/user/v1alpha1/authn")?;
let authz_url = url.join("/api/v1/user/authz")?;
Ok(Self::new(client, authn_url, authz_url, token_provider))
}
}
impl ClientCreator for drogue_client::registry::v1::Client {
fn new<TP>(client: reqwest::Client, url: Url, token_provider: TP) -> anyhow::Result<Self>
where
TP: TokenProvider + 'static,
{
Ok(Self::new(client, url, token_provider))
}
}
impl ClientCreator for drogue_client::command::v1::Client {
fn new<TP>(client: reqwest::Client, url: Url, token_provider: TP) -> anyhow::Result<Self>
where
TP: TokenProvider + 'static,
{
Ok(Self::new(client, url, token_provider))
}
}
impl ClientCreator for drogue_client::admin::v1::Client {
fn new<TP>(client: reqwest::Client, url: Url, token_provider: TP) -> anyhow::Result<Self>
where
TP: TokenProvider + 'static,
{
Ok(Self::new(client, url, token_provider))
}
}