@@ -24,16 +24,25 @@ use actix_web::{
2424 dev:: { Service , ServiceRequest , ServiceResponse , Transform , forward_ready} ,
2525 error:: { ErrorBadRequest , ErrorForbidden , ErrorUnauthorized } ,
2626 http:: header:: { self , HeaderName } ,
27+ web:: Data ,
2728} ;
29+ use chrono:: { Duration , Utc } ;
2830use futures_util:: future:: LocalBoxFuture ;
2931
3032use crate :: {
3133 handlers:: {
3234 AUTHORIZATION_KEY , KINESIS_COMMON_ATTRIBUTES_KEY , LOG_SOURCE_KEY , LOG_SOURCE_KINESIS ,
33- STREAM_NAME_HEADER_KEY ,
35+ STREAM_NAME_HEADER_KEY , http :: rbac :: RBACError ,
3436 } ,
37+ oidc:: DiscoveredClient ,
3538 option:: Mode ,
3639 parseable:: PARSEABLE ,
40+ rbac:: {
41+ EXPIRY_DURATION ,
42+ map:: { SessionKey , mut_sessions, mut_users, sessions, users} ,
43+ roles_to_permission, user,
44+ } ,
45+ utils:: get_user_from_request,
3746} ;
3847use crate :: {
3948 rbac:: Users ,
@@ -160,8 +169,97 @@ where
160169
161170 let auth_result: Result < _ , Error > = ( self . auth_method ) ( & mut req, self . action ) ;
162171
172+ let http_req = req. request ( ) . clone ( ) ;
173+ let key: Result < SessionKey , Error > = extract_session_key ( & mut req) ;
174+ let userid: Result < String , RBACError > = get_user_from_request ( & http_req) ;
175+
163176 let fut = self . service . call ( req) ;
164177 Box :: pin ( async move {
178+ let Ok ( key) = key else {
179+ return Err ( ErrorUnauthorized (
180+ "Your session has expired or is no longer valid. Please re-authenticate to access this resource." ,
181+ ) ) ;
182+ } ;
183+
184+ // if session is expired, refresh token
185+ if sessions ( ) . is_session_expired ( & key) {
186+ let oidc_client = match http_req. app_data :: < Data < Option < DiscoveredClient > > > ( ) {
187+ Some ( client) => {
188+ let c = client. clone ( ) . into_inner ( ) ;
189+ c. as_ref ( ) . clone ( )
190+ }
191+ None => None ,
192+ } ;
193+
194+ if let Some ( client) = oidc_client
195+ && let Ok ( userid) = userid
196+ {
197+ let bearer_to_refresh = {
198+ if let Some ( user) = users ( ) . get ( & userid) {
199+ match & user. ty {
200+ user:: UserType :: OAuth ( oauth) if oauth. bearer . is_some ( ) => {
201+ Some ( oauth. clone ( ) )
202+ }
203+ _ => None ,
204+ }
205+ } else {
206+ None
207+ }
208+ } ;
209+
210+ if let Some ( oauth_data) = bearer_to_refresh {
211+ let Ok ( refreshed_token) = client
212+ . refresh_token ( & oauth_data, Some ( PARSEABLE . options . scope . as_str ( ) ) )
213+ . await
214+ else {
215+ return Err ( ErrorUnauthorized (
216+ "Your session has expired or is no longer valid. Please re-authenticate to access this resource." ,
217+ ) ) ;
218+ } ;
219+
220+ let expires_in =
221+ if let Some ( expires_in) = refreshed_token. expires_in . as_ref ( ) {
222+ if * expires_in > u32:: MAX . into ( ) {
223+ EXPIRY_DURATION
224+ } else {
225+ let v = i64:: from ( * expires_in as u32 ) ;
226+ Duration :: seconds ( v)
227+ }
228+ } else {
229+ EXPIRY_DURATION
230+ } ;
231+
232+ let user_roles = {
233+ let mut users_guard = mut_users ( ) ;
234+ if let Some ( user) = users_guard. get_mut ( & userid) {
235+ if let user:: UserType :: OAuth ( oauth) = & mut user. ty {
236+ oauth. bearer = Some ( refreshed_token) ;
237+ }
238+ user. roles ( ) . to_vec ( )
239+ } else {
240+ return Err ( ErrorUnauthorized (
241+ "Your session has expired or is no longer valid. Please re-authenticate to access this resource." ,
242+ ) ) ;
243+ }
244+ } ;
245+
246+ mut_sessions ( ) . track_new (
247+ userid. clone ( ) ,
248+ key. clone ( ) ,
249+ Utc :: now ( ) + expires_in,
250+ roles_to_permission ( user_roles) ,
251+ ) ;
252+ } else if let Some ( user) = users ( ) . get ( & userid) {
253+ mut_sessions ( ) . track_new (
254+ userid. clone ( ) ,
255+ key. clone ( ) ,
256+ Utc :: now ( ) + EXPIRY_DURATION ,
257+ roles_to_permission ( user. roles ( ) ) ,
258+ ) ;
259+ }
260+ }
261+ }
262+
165263 match auth_result? {
166264 rbac:: Response :: UnAuthorized => {
167265 return Err ( ErrorForbidden (
0 commit comments