@@ -2,7 +2,6 @@ use std::sync::Arc;
22
33use async_trait:: async_trait;
44use dashmap:: DashMap ;
5- use derive_builder:: Builder ;
65use jsonwebtoken:: { jwk:: JwkSet , DecodingKey , TokenData , Validation } ;
76use serde:: de:: DeserializeOwned ;
87use tokio:: sync:: Notify ;
@@ -14,16 +13,13 @@ const DEFAULT_RETRY_COUNT: usize = 3; // 3 attempts
1413const DEFAULT_BACKOFF : std:: time:: Duration = std:: time:: Duration :: from_secs ( 1 ) ; // 1 second
1514
1615/// Configuration for remote JWKS fetching and caching behavior.
17- #[ derive( Debug , Clone , Builder ) ]
16+ #[ derive( Debug , Clone ) ]
1817pub struct RemoteJwksDecoderConfig {
1918 /// Duration to cache JWKS keys before refreshing (default: 1 hour)
20- #[ builder( default = "DEFAULT_CACHE_DURATION" ) ]
2119 pub cache_duration : std:: time:: Duration ,
2220 /// Number of retry attempts when fetching JWKS fails (default: 3)
23- #[ builder( default = "DEFAULT_RETRY_COUNT" ) ]
2421 pub retry_count : usize ,
2522 /// Delay between retry attempts (default: 1 second)
26- #[ builder( default = "DEFAULT_BACKOFF" ) ]
2723 pub backoff : std:: time:: Duration ,
2824}
2925
@@ -40,7 +36,47 @@ impl Default for RemoteJwksDecoderConfig {
4036impl RemoteJwksDecoderConfig {
4137 /// Creates a new builder for configuring JWKS fetching behavior.
4238 pub fn builder ( ) -> RemoteJwksDecoderConfigBuilder {
43- RemoteJwksDecoderConfigBuilder :: default ( )
39+ RemoteJwksDecoderConfigBuilder {
40+ cache_duration : None ,
41+ retry_count : None ,
42+ backoff : None ,
43+ }
44+ }
45+ }
46+
47+ /// Builder for `RemoteJwksDecoderConfig`.
48+ pub struct RemoteJwksDecoderConfigBuilder {
49+ cache_duration : Option < std:: time:: Duration > ,
50+ retry_count : Option < usize > ,
51+ backoff : Option < std:: time:: Duration > ,
52+ }
53+
54+ impl RemoteJwksDecoderConfigBuilder {
55+ /// Sets the cache duration.
56+ pub fn cache_duration ( mut self , cache_duration : std:: time:: Duration ) -> Self {
57+ self . cache_duration = Some ( cache_duration) ;
58+ self
59+ }
60+
61+ /// Sets the retry count.
62+ pub fn retry_count ( mut self , retry_count : usize ) -> Self {
63+ self . retry_count = Some ( retry_count) ;
64+ self
65+ }
66+
67+ /// Sets the backoff duration.
68+ pub fn backoff ( mut self , backoff : std:: time:: Duration ) -> Self {
69+ self . backoff = Some ( backoff) ;
70+ self
71+ }
72+
73+ /// Builds the `RemoteJwksDecoderConfig` with defaults for unset fields.
74+ pub fn build ( self ) -> RemoteJwksDecoderConfig {
75+ RemoteJwksDecoderConfig {
76+ cache_duration : self . cache_duration . unwrap_or ( DEFAULT_CACHE_DURATION ) ,
77+ retry_count : self . retry_count . unwrap_or ( DEFAULT_RETRY_COUNT ) ,
78+ backoff : self . backoff . unwrap_or ( DEFAULT_BACKOFF ) ,
79+ }
4480 }
4581}
4682
@@ -67,23 +103,19 @@ impl RemoteJwksDecoderConfig {
67103/// decoder_clone.refresh_keys_periodically().await;
68104/// });
69105/// ```
70- #[ derive( Clone , Builder ) ]
106+ #[ derive( Clone ) ]
71107pub struct RemoteJwksDecoder {
72108 /// The JWKS endpoint URL
73109 jwks_url : String ,
74110 /// Configuration for caching and retry behavior
75- #[ builder( default = "RemoteJwksDecoderConfig::default()" ) ]
76111 config : RemoteJwksDecoderConfig ,
77112 /// Thread-safe cache mapping key IDs to decoding keys
78- #[ builder( default = "Arc::new(DashMap::new())" ) ]
79113 keys_cache : Arc < DashMap < String , DecodingKey > > ,
80114 /// JWT validation settings
81115 validation : Validation ,
82116 /// HTTP client for fetching JWKS
83- #[ builder( default = "reqwest::Client::new()" ) ]
84117 client : reqwest:: Client ,
85118 /// Notification for initialization completion
86- #[ builder( default = "Arc::new(Notify::new())" ) ]
87119 initialized : Arc < Notify > ,
88120}
89121
@@ -94,15 +126,12 @@ impl RemoteJwksDecoder {
94126 ///
95127 /// Returns `Error::Configuration` if the builder fails to construct the decoder.
96128 pub fn new ( jwks_url : String ) -> Result < Self , Error > {
97- RemoteJwksDecoderBuilder :: default ( )
98- . jwks_url ( jwks_url)
99- . build ( )
100- . map_err ( |e| Error :: Configuration ( e. to_string ( ) ) )
129+ RemoteJwksDecoderBuilder :: new ( ) . jwks_url ( jwks_url) . build ( )
101130 }
102131
103132 /// Creates a new builder for configuring a remote JWKS decoder.
104133 pub fn builder ( ) -> RemoteJwksDecoderBuilder {
105- RemoteJwksDecoderBuilder :: default ( )
134+ RemoteJwksDecoderBuilder :: new ( )
106135 }
107136
108137 /// Refreshes the JWKS cache with retry logic.
@@ -221,6 +250,96 @@ impl RemoteJwksDecoder {
221250 }
222251}
223252
253+ /// Builder for `RemoteJwksDecoder`.
254+ pub struct RemoteJwksDecoderBuilder {
255+ jwks_url : Option < String > ,
256+ config : Option < RemoteJwksDecoderConfig > ,
257+ keys_cache : Option < Arc < DashMap < String , DecodingKey > > > ,
258+ validation : Option < Validation > ,
259+ client : Option < reqwest:: Client > ,
260+ initialized : Option < Arc < Notify > > ,
261+ }
262+
263+ impl RemoteJwksDecoderBuilder {
264+ /// Creates a new `RemoteJwksDecoderBuilder`.
265+ pub fn new ( ) -> Self {
266+ Self {
267+ jwks_url : None ,
268+ config : None ,
269+ keys_cache : None ,
270+ validation : None ,
271+ client : None ,
272+ initialized : None ,
273+ }
274+ }
275+
276+ /// Sets the JWKS URL.
277+ pub fn jwks_url ( mut self , jwks_url : String ) -> Self {
278+ self . jwks_url = Some ( jwks_url) ;
279+ self
280+ }
281+
282+ /// Sets the configuration.
283+ pub fn config ( mut self , config : RemoteJwksDecoderConfig ) -> Self {
284+ self . config = Some ( config) ;
285+ self
286+ }
287+
288+ /// Sets the keys cache.
289+ pub fn keys_cache ( mut self , keys_cache : Arc < DashMap < String , DecodingKey > > ) -> Self {
290+ self . keys_cache = Some ( keys_cache) ;
291+ self
292+ }
293+
294+ /// Sets the validation settings.
295+ pub fn validation ( mut self , validation : Validation ) -> Self {
296+ self . validation = Some ( validation) ;
297+ self
298+ }
299+
300+ /// Sets the HTTP client.
301+ pub fn client ( mut self , client : reqwest:: Client ) -> Self {
302+ self . client = Some ( client) ;
303+ self
304+ }
305+
306+ /// Sets the initialized notifier.
307+ pub fn initialized ( mut self , initialized : Arc < Notify > ) -> Self {
308+ self . initialized = Some ( initialized) ;
309+ self
310+ }
311+
312+ /// Builds the `RemoteJwksDecoder`.
313+ ///
314+ /// # Errors
315+ ///
316+ /// Returns `Error::Configuration` if required fields are missing.
317+ pub fn build ( self ) -> Result < RemoteJwksDecoder , Error > {
318+ let jwks_url = self
319+ . jwks_url
320+ . ok_or_else ( || Error :: Configuration ( "jwks_url is required" . into ( ) ) ) ?;
321+
322+ let validation = self
323+ . validation
324+ . ok_or_else ( || Error :: Configuration ( "validation is required" . into ( ) ) ) ?;
325+
326+ Ok ( RemoteJwksDecoder {
327+ jwks_url,
328+ config : self . config . unwrap_or_default ( ) ,
329+ keys_cache : self . keys_cache . unwrap_or_else ( || Arc :: new ( DashMap :: new ( ) ) ) ,
330+ validation,
331+ client : self . client . unwrap_or_default ( ) ,
332+ initialized : self . initialized . unwrap_or_else ( || Arc :: new ( Notify :: new ( ) ) ) ,
333+ } )
334+ }
335+ }
336+
337+ impl Default for RemoteJwksDecoderBuilder {
338+ fn default ( ) -> Self {
339+ Self :: new ( )
340+ }
341+ }
342+
224343#[ async_trait]
225344impl < T > JwtDecoder < T > for RemoteJwksDecoder
226345where
0 commit comments