Skip to main content

axum_oidc_layer/cache/
mod.rs

1//! Caching functionality for OIDC authentication.
2//!
3//! This module provides caching traits and type-safe cache key wrappers
4//! to efficiently store OIDC configuration, JWKS keys, and token validation results.
5
6use std::{
7    collections::hash_map::DefaultHasher,
8    hash::{Hash, Hasher},
9    time::Duration,
10};
11
12pub mod memory;
13
14pub use memory::InMemoryCache;
15
16/// Trait for caching `JWKS` keys and `OIDC` configuration.
17///
18/// This trait allows users to implement custom caching strategies,
19/// such as Redis, database, or custom in-memory implementations.
20pub trait JwksCache: Send + Sync {
21    /// Retrieves a cached value by key.
22    /// Returns `None` if the key doesn't exist or has expired.
23    fn get(&self, key: &str) -> Option<String>;
24
25    /// Stores a value in the cache with the specified TTL.
26    fn set(&self, key: &str, value: String, ttl: Duration);
27}
28
29/// Type-safe cache key for JWT tokens.
30///
31/// Prevents accidentally mixing token cache keys with other cache key types.
32#[derive(Debug, Clone, PartialEq, Eq, Hash)]
33pub struct TokenCacheKey(String);
34
35impl TokenCacheKey {
36    /// Creates a cache key from a JWT token by hashing it.
37    #[must_use]
38    pub fn from_token(token: &str) -> Self {
39        let mut hasher = DefaultHasher::new();
40        token.hash(&mut hasher);
41        Self(format!("token:{}", hasher.finish()))
42    }
43
44    /// Creates a cache key from a token and validation context.
45    #[must_use]
46    pub fn from_token_with_context(
47        token: &str,
48        issuer: Option<&str>,
49        audience: Option<&[String]>,
50    ) -> Self {
51        let mut hasher = DefaultHasher::new();
52        token.hash(&mut hasher);
53        issuer.hash(&mut hasher);
54        if let Some(audience) = audience {
55            for value in audience {
56                value.hash(&mut hasher);
57            }
58        }
59        Self(format!("token:{}", hasher.finish()))
60    }
61
62    /// Returns the cache key as a string.
63    #[must_use]
64    pub fn as_str(&self) -> &str {
65        &self.0
66    }
67}
68
69/// Type-safe cache key for OIDC configuration.
70///
71/// Prevents accidentally mixing config cache keys with other cache key types.
72#[derive(Debug, Clone, PartialEq, Eq, Hash)]
73pub struct ConfigCacheKey(String);
74
75impl ConfigCacheKey {
76    /// Creates a cache key for OIDC configuration.
77    #[must_use]
78    pub fn from_url(url: &str) -> Self {
79        Self(format!("config:{url}"))
80    }
81
82    /// Returns the cache key as a string.
83    #[must_use]
84    pub fn as_str(&self) -> &str {
85        &self.0
86    }
87}
88
89/// Type-safe cache key for individual JWK keys.
90///
91/// Prevents accidentally mixing JWK cache keys with other cache key types.
92#[derive(Debug, Clone, PartialEq, Eq, Hash)]
93pub struct JwkCacheKey(String);
94
95impl JwkCacheKey {
96    /// Creates a cache key for a specific JWK.
97    #[must_use]
98    pub fn from_jwks_uri_and_kid(jwks_uri: &str, kid: &str) -> Self {
99        Self(format!("jwk:{jwks_uri}:{kid}"))
100    }
101
102    /// Returns the cache key as a string.
103    #[must_use]
104    pub fn as_str(&self) -> &str {
105        &self.0
106    }
107}