1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
use super::{Jwk, KeyPair};
use serde::Serialize;
/// Represents a JSON Web Key Set (JWKS).
///
/// JWKS is a set of keys containing the cryptographic information
/// required to verify tokens or signatures. This struct is typically
/// used to convey public keys in a JWKS endpoint.
#[derive(Serialize)]
pub struct Jwks {
/// A collection of `Jwk` objects, each representing a public key.
pub keys: Vec<Jwk>,
}
impl Jwks {
/// Filters and returns a `Jwks` instance containing only the non-expired keys
/// from the given `key_pairs`.
///
/// This method is used to prepare a JWKS response with valid keys, omitting
/// any that have expired.
///
/// # Arguments
///
/// * `key_pairs` - A vector of `KeyPair` instances.
///
/// # Returns
///
/// Returns a `Jwks` instance containing only valid, non-expired `Jwk` keys.
pub fn from_valid_pairs(key_pairs: Vec<KeyPair>) -> Self {
Self {
keys: key_pairs
.into_iter()
.filter_map(|jwt_key| {
if !jwt_key.is_expired() {
Some(Jwk::new(&jwt_key.kid, &jwt_key.public_key))
} else {
None
}
})
.collect(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn mock_key_pair(kid: &str, is_expired: bool) -> KeyPair {
let expiration = if is_expired { -72_000 } else { 72_000 };
KeyPair::new(&kid.to_string(), expiration).unwrap()
}
#[test]
fn test_from_valid_pairs() {
let key_pairs = vec![
mock_key_pair("valid1", false),
mock_key_pair("expired1", true),
mock_key_pair("valid2", false),
mock_key_pair("expired2", true),
mock_key_pair("valid3", false),
mock_key_pair("valid4", false),
mock_key_pair("expired3", true),
mock_key_pair("valid5", false),
];
let jwks = Jwks::from_valid_pairs(key_pairs);
assert_eq!(
jwks.keys.len(),
5,
"Jwks should only include non-expired keys."
);
}
}