keycloak-access 0.0.1

Keycloak generated jwt access validation
Documentation
use std::sync::Arc;

use serde::de::DeserializeOwned;

use super::config::KeycloakConfig;
use crate::error::Error;

#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct RealmInfo {
    #[serde(default)]
    pub realm: Option<Arc<str>>,
    #[serde(default)]
    pub public_key: Option<Arc<str>>,
}

struct Inner {
    url: Arc<str>,
    public_url: Arc<str>,
    client: reqwest::Client,
}

#[derive(Clone)]
pub struct Keycloak {
    inner: Arc<Inner>,
}

fn info_url(url: &str, realm: &str) -> String {
    format!("{url}/realms/{realm}")
}

impl Keycloak {
    pub fn new(config: &KeycloakConfig) -> Self {
        let url = config.address();
        let public_url = config.public_url();
        let client = reqwest::Client::new();
        Self {
            inner: Arc::new(Inner {
                url,
                public_url,
                client,
            }),
        }
    }

    pub fn public_url(&self) -> &str {
        self.inner.public_url.as_ref()
    }

    async fn fetch<T>(&self, url: &str) -> Result<T, Error>
    where
        T: DeserializeOwned,
    {
        Ok(self.inner.client.get(url).send().await?.json::<T>().await?)
    }

    pub async fn info(&self, realm: &str) -> Result<RealmInfo, Error> {
        self.fetch(&info_url(&self.inner.url, realm)).await
    }
}