@@ -107,31 +107,29 @@ impl App {
107107 capability : models:: Capability ,
108108 ) -> Result < Vec < String > , ApiError > {
109109 let is_blocking = req_started_at. is_none ( ) ;
110+ let started_at = req_started_at. unwrap_or ( chrono:: Utc :: now ( ) ) ;
110111 loop {
111- match Snapshot :: evaluate (
112- & self . snapshot ,
113- req_started_at. unwrap_or ( chrono:: Utc :: now ( ) ) ,
114- |snapshot : & Snapshot | {
115- for prefix in & prefixes_or_names {
116- if !tables:: UserGrant :: is_authorized (
117- & snapshot. role_grants ,
118- & snapshot. user_grants ,
119- claims. sub ,
120- prefix,
121- capability,
122- ) {
123- return Err ( ApiError :: unauthorized ( prefix. as_str ( ) ) ) ;
124- }
112+ match Snapshot :: evaluate ( & self . snapshot , started_at, |snapshot : & Snapshot | {
113+ for prefix in & prefixes_or_names {
114+ if !tables:: UserGrant :: is_authorized (
115+ & snapshot. role_grants ,
116+ & snapshot. user_grants ,
117+ claims. sub ,
118+ prefix,
119+ capability,
120+ ) {
121+ return Err ( ApiError :: unauthorized ( prefix. as_str ( ) ) ) ;
125122 }
126- Ok ( ( None , ( ) ) )
127- } ,
128- ) {
123+ }
124+ Ok ( ( None , ( ) ) )
125+ } ) {
129126 Ok ( ( _exp, ( ) ) ) => return Ok ( prefixes_or_names) ,
130127 Err ( Ok ( backoff) ) if is_blocking => {
131128 tracing:: debug!( ?backoff, "waiting before retrying authZ check" ) ;
132129 ( ) = tokio:: time:: sleep ( backoff) . await ;
133130 }
134131 Err ( Ok ( backoff) ) => {
132+ // Don't use `req_started_at` when computing the retry time, as that value comes from the client.
135133 return Err ( ApiError :: retry_authz_failure ( chrono:: Utc :: now ( ) + backoff) ) ;
136134 }
137135 Err ( Err ( err) ) => return Err ( err) ,
0 commit comments