google_oauth/
certs.rs

1#[cfg(not(feature = "wasm"))]
2use std::time::Instant;
3#[cfg(feature = "wasm")]
4use web_time::Instant;
5use log::debug;
6use serde::{Deserialize, Serialize};
7use crate::{IDTokenCertNotFoundError, MyResult};
8
9#[derive(Serialize, Deserialize, Debug, Default)]
10pub struct Certs {
11    keys: Vec<Cert>,
12
13    /// MUST refresh certs from Google server again, when one of following is matched:
14    /// 1. cache_until is None,
15    /// 2. if let Some(time) = cache_until, current time > time
16    #[serde(skip)]
17    cache_until: Option<Instant>,
18}
19
20#[derive(Serialize, Deserialize, Debug, Clone)]
21pub struct Cert {
22    pub kid: String,
23    pub e: String,
24    pub alg: String,
25    pub kty: String,
26    pub n: String,
27}
28
29impl Certs {
30    pub fn find_cert<T: AsRef<str>>(&self, alg: T, kid: T) -> MyResult<Cert> {
31        let alg = alg.as_ref();
32        let kid = kid.as_ref();
33
34        match self.keys.iter().find(|cert| cert.alg == alg && cert.kid == kid) {
35            Some(cert ) => Ok(cert.clone()),
36            None => Err(IDTokenCertNotFoundError::new(alg, kid))?,
37        }
38    }
39
40    #[inline]
41    pub fn set_cache_until<T>(&mut self, cache_until: T)
42        where T: Into<Option<Instant>>
43    {
44        let cache_until = cache_until.into();
45
46        debug!("set cache until to {:?}", cache_until);
47        self.cache_until = cache_until;
48    }
49
50    #[inline]
51    pub fn need_refresh(&self) -> bool {
52        self
53            .cache_until
54            .map(|until| until <= Instant::now())
55            .unwrap_or(true)
56    }
57}