From 3c18748f50b8035ee81600aab28643b3447efc90 Mon Sep 17 00:00:00 2001 From: Bittrance Date: Sat, 22 Jun 2024 07:07:14 +0200 Subject: [PATCH 1/2] feat: Builder for remote verifier. This means the caller will not have to care about vaules with defaults. --- examples/jwks_client.rs | 7 +---- src/jwk.rs | 70 ++++++++++++++++++++++++++++++----------- 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/examples/jwks_client.rs b/examples/jwks_client.rs index 4a68cf7..19a9810 100644 --- a/examples/jwks_client.rs +++ b/examples/jwks_client.rs @@ -4,7 +4,6 @@ async fn main() -> jwtk::Result<()> { use jwtk::jwk::RemoteJwksVerifier; use serde::Deserialize; use serde_json::{Map, Value}; - use std::time::Duration; #[derive(Deserialize)] struct Token { @@ -16,11 +15,7 @@ async fn main() -> jwtk::Result<()> { .json() .await?; - let j = RemoteJwksVerifier::new( - "http://127.0.0.1:3000/jwks".into(), - None, - Duration::from_secs(300), - ); + let j = RemoteJwksVerifier::new("http://127.0.0.1:3000/jwks".into()); let c = j.verify::>(&v.token).await?; println!("headers:\n{}", serde_json::to_string(c.header())?); diff --git a/src/jwk.rs b/src/jwk.rs index 117344e..7bb19e4 100644 --- a/src/jwk.rs +++ b/src/jwk.rs @@ -450,26 +450,18 @@ pub struct RemoteJwksVerifier { #[cfg(feature = "remote-jwks")] impl RemoteJwksVerifier { - pub fn new( - url: String, - client: Option, - cache_duration: std::time::Duration, - ) -> Self { - Self { - url, - client: client.unwrap_or_default(), - cache_duration, - cache: tokio::sync::RwLock::new(None), - require_kid: true, - } + /// Construct a new RemoteJwksVerifier with default settings. + pub fn new(url: String) -> Self { + Self::builder(url).build() } - /// If called with `false`, subsequent `verify` and `verify_only` calls will - /// try all keys from the key set if a `kid` is not specified in the token. - pub fn set_require_kid(&mut self, required: bool) { - self.require_kid = required; - if let Some(ref mut v) = self.cache.get_mut() { - v.jwks.require_kid = required; + /// Construct a customized RemoteJwksVerifier. + pub fn builder(url: String) -> RemoteJwksVerifierBuilder { + RemoteJwksVerifierBuilder { + url, + client: None, + cache_duration: None, + require_kid: true, } } @@ -535,6 +527,48 @@ impl RemoteJwksVerifier { } } +pub struct RemoteJwksVerifierBuilder { + url: String, + client: Option, + cache_duration: Option, + require_kid: bool, +} + +impl RemoteJwksVerifierBuilder { + /// Provide an HTTP client for fetching the JWK set. + pub fn with_client(mut self, client: reqwest::Client) -> Self { + self.client = Some(client); + self + } + + /// Set how long the fetched JWK set should be cached. Default is + /// 5 minutes. + pub fn with_cache_duration(mut self, duration: std::time::Duration) -> Self { + self.cache_duration = Some(duration); + self + } + + /// Calls to `verify` and `verify_only` calls will try all keys + /// from the key set if a `kid` is not specified in the token. + pub fn with_kid_optional(mut self) -> Self { + self.require_kid = false; + self + } + + /// Construct the RemoteJwksVerifier. + pub fn build(self) -> RemoteJwksVerifier { + RemoteJwksVerifier { + url: self.url, + client: self.client.unwrap_or_default(), + cache_duration: self + .cache_duration + .unwrap_or_else(|| std::time::Duration::from_secs(300)), + cache: tokio::sync::RwLock::new(None), + require_kid: self.require_kid, + } + } +} + #[cfg(test)] mod tests { use crate::{ From 68355773d7021ed298f0ca5def1cf7c35a5bcee6 Mon Sep 17 00:00:00 2001 From: Bittrance Date: Sat, 22 Jun 2024 07:16:46 +0200 Subject: [PATCH 2/2] fixup! feat: Builder for remote verifier. --- src/jwk.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/jwk.rs b/src/jwk.rs index 7bb19e4..24d8386 100644 --- a/src/jwk.rs +++ b/src/jwk.rs @@ -527,6 +527,7 @@ impl RemoteJwksVerifier { } } +#[cfg(feature = "remote-jwks")] pub struct RemoteJwksVerifierBuilder { url: String, client: Option, @@ -534,6 +535,7 @@ pub struct RemoteJwksVerifierBuilder { require_kid: bool, } +#[cfg(feature = "remote-jwks")] impl RemoteJwksVerifierBuilder { /// Provide an HTTP client for fetching the JWK set. pub fn with_client(mut self, client: reqwest::Client) -> Self {