1use chrono::Utc;
2use k8s_openapi::api::authentication::v1::{TokenReviewSpec, TokenReviewStatus};
3use ref_cast::RefCast;
4use std::collections::HashMap;
5use std::hash::{Hash, Hasher};
6
7#[derive(Default)]
8pub struct Cache {
9 map: HashMap<Spec, TokenReviewStatus>,
10}
11
12impl Cache {
13 pub fn new() -> Self {
14 Self::default()
15 }
16
17 pub fn get(&self, spec: &TokenReviewSpec) -> Option<&TokenReviewStatus> {
18 if crate::exp(spec) > Some(Utc::now().timestamp()) {
19 self.map.get(Spec::ref_cast(spec))
20 } else {
21 None
22 }
23 }
24
25 pub fn put(&mut self, spec: TokenReviewSpec, status: TokenReviewStatus) {
26 self.map.insert(Spec(spec), status);
27
28 let now = Utc::now().timestamp();
29 self.map.retain(|spec, _| crate::exp(&spec.0) > Some(now));
30 }
31}
32
33#[derive(Clone, PartialEq, RefCast)]
34#[repr(transparent)]
35struct Spec(TokenReviewSpec);
36
37impl Eq for Spec {}
38
39impl Hash for Spec {
40 fn hash<H>(&self, state: &mut H)
41 where
42 H: Hasher,
43 {
44 let TokenReviewSpec { audiences, token } = &self.0;
45 audiences.hash(state);
46 token.hash(state);
47 }
48}