#[cfg(all(feature = "moka", not(target_arch = "wasm32")))]
pub mod moka;
use crate::error::Result;
use crate::jwk::Key;
use super::{KeySet, KeyStore};
#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
pub trait KeyCache {
async fn get(&self) -> Result<Option<KeySet>>;
async fn set(&self, keyset: KeySet) -> Result<()>;
async fn clear(&self) -> Result<()>;
}
#[derive(Debug)]
pub struct CachedKeyStore<C: KeyCache, S: KeyStore> {
cache: C,
store: S,
}
impl<C: KeyCache, S: KeyStore> CachedKeyStore<C, S> {
pub fn new(cache: C, store: S) -> Self {
Self { cache, store }
}
pub fn cache(&self) -> &C {
&self.cache
}
pub fn store(&self) -> &S {
&self.store
}
}
#[cfg(not(target_arch = "wasm32"))]
#[async_trait::async_trait]
impl<C, S> KeyStore for CachedKeyStore<C, S>
where
C: KeyCache + Send + Sync,
S: KeyStore + Send + Sync,
{
async fn get_keyset(&self) -> Result<KeySet> {
if let Some(keyset) = self.cache.get().await? {
return Ok(keyset);
}
let keyset = self.store.get_keyset().await?;
self.cache.set(keyset.clone()).await?;
Ok(keyset)
}
async fn get_key(&self, kid: &str) -> Result<Option<Key>> {
if let Some(keyset) = self.cache.get().await?
&& let Some(key) = keyset.get_by_kid(kid)
{
return Ok(Some(key.clone()));
}
let keyset = self.store.get_keyset().await?;
self.cache.set(keyset.clone()).await?;
Ok(keyset.get_by_kid(kid).cloned())
}
}
#[cfg(target_arch = "wasm32")]
#[async_trait::async_trait(?Send)]
impl<C, S> KeyStore for CachedKeyStore<C, S>
where
C: KeyCache,
S: KeyStore,
{
async fn get_keyset(&self) -> Result<KeySet> {
if let Some(keyset) = self.cache.get().await? {
return Ok(keyset);
}
let keyset = self.store.get_keyset().await?;
self.cache.set(keyset.clone()).await?;
Ok(keyset)
}
async fn get_key(&self, kid: &str) -> Result<Option<Key>> {
if let Some(keyset) = self.cache.get().await?
&& let Some(key) = keyset.get_by_kid(kid)
{
return Ok(Some(key.clone()));
}
let keyset = self.store.get_keyset().await?;
self.cache.set(keyset.clone()).await?;
Ok(keyset.get_by_kid(kid).cloned())
}
}