This repository has been archived by the owner on Dec 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Moved the CertificatesCache to its own module and added a test …
…for it
- Loading branch information
1 parent
0fd4ac5
commit ca71942
Showing
4 changed files
with
115 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ edition = "2021" | |
name = "ids-daps-client" | ||
description = "A client to connect with the IDS DAPS." | ||
version = "0.1.0" | ||
license-file = "LICENSE" | ||
license = "Apache-2.0" | ||
repository = "https://github.com/truzzt/ids-daps-client-rs" | ||
readme = "README.md" | ||
authors = ["Maximilian Schoenenberg <[email protected]>"] | ||
|
@@ -20,7 +20,7 @@ derive_builder = "0.20.0" | |
jsonwebtoken = "9.3.0" | ||
openssl = "0.10.66" | ||
reqwest = { version = "0.12.5", features = ["json", "http2"], optional = true} | ||
serde = { version = "1.0.204", features = ["derive"] } | ||
serde = { version = "1", features = ["derive"] } | ||
thiserror = "1" | ||
tracing = "0.1.40" | ||
url = "2.5.2" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
//! Cache for the certificates of the DAPS Client. | ||
/// An error that can occur when accessing the `CertificatesCache`. | ||
#[derive(thiserror::Error, Debug, PartialEq)] | ||
pub enum CertificatesCacheError { | ||
#[error("Cache is outdated")] | ||
Outdated, | ||
#[error("Cache is empty")] | ||
Empty, | ||
} | ||
|
||
/// A cache for the certificates of the DAPS. | ||
#[derive(Debug, Default)] | ||
pub(crate) struct CertificatesCache { | ||
/// The cache of certificates. | ||
inner: async_lock::RwLock<Option<CertificatesCacheStorage>>, | ||
/// The TTL of the cache. | ||
ttl: std::time::Duration, | ||
} | ||
|
||
impl CertificatesCache { | ||
#[must_use] | ||
pub(crate) fn new(ttl: std::time::Duration) -> Self { | ||
Self { | ||
ttl, | ||
..Default::default() | ||
} | ||
} | ||
|
||
pub(crate) async fn get(&self) -> Result<jsonwebtoken::jwk::JwkSet, CertificatesCacheError> { | ||
let cache = self.inner.read().await; | ||
if let Some(cache) = &*cache { | ||
if cache.stored + self.ttl < chrono::Utc::now() { | ||
Err(CertificatesCacheError::Outdated) | ||
} else { | ||
Ok(cache.jwks.clone()) | ||
} | ||
} else { | ||
Err(CertificatesCacheError::Empty) | ||
} | ||
} | ||
|
||
pub(crate) async fn update( | ||
&self, | ||
jwks: jsonwebtoken::jwk::JwkSet, | ||
) -> Result<jsonwebtoken::jwk::JwkSet, CertificatesCacheError> { | ||
let mut cache = self.inner.write().await; | ||
let new_cache = CertificatesCacheStorage { | ||
jwks: jwks.clone(), | ||
stored: chrono::Utc::now(), | ||
}; | ||
*cache = Some(new_cache); | ||
|
||
Ok(jwks) | ||
} | ||
} | ||
|
||
/// The storage of the cache. | ||
#[derive(Debug)] | ||
struct CertificatesCacheStorage { | ||
/// Timestamp of the last storage of the certificates. | ||
stored: chrono::DateTime<chrono::Utc>, | ||
/// The cache of certificates. | ||
jwks: jsonwebtoken::jwk::JwkSet, | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
|
||
#[tokio::test] | ||
async fn certificate_cache() { | ||
use super::*; | ||
|
||
let cache = CertificatesCache::new(std::time::Duration::from_secs(1)); | ||
assert_eq!(Err(CertificatesCacheError::Empty), cache.get().await); | ||
|
||
let jwks = jsonwebtoken::jwk::JwkSet { keys: vec![] }; | ||
cache.update(jwks.clone()).await.unwrap(); | ||
assert_eq!(Ok(jwks), cache.get().await); | ||
|
||
tokio::time::sleep(std::time::Duration::from_secs(2)).await; | ||
assert_eq!(Err(CertificatesCacheError::Outdated), cache.get().await); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters