drogue_bazaar/client/
mod.rs

1//! Working with API clients.
2
3use crate::{auth::openid::TokenConfig, reqwest::ClientFactory};
4use async_trait::async_trait;
5use drogue_client::openid::TokenProvider;
6use url::Url;
7
8/// A standard API client configuration.
9#[derive(Clone, Debug, serde::Deserialize)]
10pub struct ClientConfig {
11    pub url: Url,
12
13    #[serde(flatten, default)]
14    pub token_config: Option<TokenConfig>,
15}
16
17impl ClientConfig {
18    /// Convert into a client.
19    pub async fn into_client<T>(self) -> anyhow::Result<T>
20    where
21        T: ClientCreator,
22    {
23        let token = if let Some(token) = self.token_config {
24            Some(token.discover_from().await?)
25        } else {
26            None
27        };
28
29        T::new(ClientFactory::new().build()?, self.url, token)
30    }
31}
32
33/// Create a new client from a URL, an HTTP client, and a token provider.
34#[async_trait]
35pub trait ClientCreator: Sized {
36    fn new<TP>(client: reqwest::Client, url: Url, token_provider: TP) -> anyhow::Result<Self>
37    where
38        TP: TokenProvider + 'static;
39}
40
41impl ClientCreator for drogue_client::user::v1::Client {
42    fn new<TP>(client: reqwest::Client, url: Url, token_provider: TP) -> anyhow::Result<Self>
43    where
44        TP: TokenProvider + 'static,
45    {
46        let authn_url = url.join("/api/user/v1alpha1/authn")?;
47        let authz_url = url.join("/api/v1/user/authz")?;
48
49        Ok(Self::new(client, authn_url, authz_url, token_provider))
50    }
51}
52
53impl ClientCreator for drogue_client::registry::v1::Client {
54    fn new<TP>(client: reqwest::Client, url: Url, token_provider: TP) -> anyhow::Result<Self>
55    where
56        TP: TokenProvider + 'static,
57    {
58        Ok(Self::new(client, url, token_provider))
59    }
60}
61
62impl ClientCreator for drogue_client::command::v1::Client {
63    fn new<TP>(client: reqwest::Client, url: Url, token_provider: TP) -> anyhow::Result<Self>
64    where
65        TP: TokenProvider + 'static,
66    {
67        Ok(Self::new(client, url, token_provider))
68    }
69}
70
71impl ClientCreator for drogue_client::admin::v1::Client {
72    fn new<TP>(client: reqwest::Client, url: Url, token_provider: TP) -> anyhow::Result<Self>
73    where
74        TP: TokenProvider + 'static,
75    {
76        Ok(Self::new(client, url, token_provider))
77    }
78}