use crate::algorithm::AlgorithmType;
use crate::discovery::discover_jwks_uri;
use crate::error::Result;
use crate::jwks::{JwkSet, fetch_jwks, find_key_by_kid};
use crate::utils::bounds::is_valid_cache_key;
use moka::future::Cache;
use std::sync::Arc;
pub(crate) async fn resolve_key_from_issuer(
client: &reqwest::Client,
issuer: &str,
algorithm: &AlgorithmType,
kid: Option<&str>,
cache: Option<Arc<Cache<String, Vec<u8>>>>,
) -> Result<Vec<u8>> {
let cache_key = if cache.is_some() {
let kid_str = kid.unwrap_or("");
let key = format!("{}|{}|{}", issuer, algorithm.as_str(), kid_str);
if is_valid_cache_key(&key) {
Some(key)
} else {
None
}
} else {
None
};
if let (Some(cache_ref), Some(key)) = (&cache, &cache_key) {
if let Some(cached_key) = cache_ref.get(key).await {
return Ok(cached_key);
}
}
let jwks_uri = discover_jwks_uri(issuer, client).await?;
let jwks: JwkSet = fetch_jwks(client, &jwks_uri).await?;
let jwk = find_key_by_kid(&jwks, kid)?;
let key_der = jwk.to_key(algorithm, true)?;
if let (Some(cache_ref), Some(key)) = (&cache, cache_key) {
cache_ref.insert(key, key_der.clone()).await;
}
Ok(key_der)
}