@@ -403,7 +403,9 @@ async fn handle_unauthenticated_request(
403403 log:: debug!( "Redirecting to OIDC provider" ) ;
404404
405405 let initial_url = request. uri ( ) . to_string ( ) ;
406- let response = build_auth_provider_redirect_response ( oidc_state, & initial_url) . await ;
406+ let redirect_count = get_redirect_count ( & request) ;
407+ let response =
408+ build_auth_provider_redirect_response ( oidc_state, & initial_url, redirect_count) . await ;
407409 MiddlewareResponse :: Respond ( request. into_response ( response) )
408410}
409411
@@ -413,25 +415,40 @@ async fn handle_oidc_callback(oidc_state: &OidcState, request: ServiceRequest) -
413415 clear_redirect_count_cookie ( & mut response) ;
414416 request. into_response ( response)
415417 }
416- Err ( e) => {
417- let redirect_count = get_redirect_count ( & request) ;
418- if redirect_count >= MAX_OIDC_REDIRECTS {
419- log:: error!(
420- "Failed to process OIDC callback after {redirect_count} attempts. \
421- Stopping to avoid infinite redirections: {e:#}"
422- ) ;
423- let resp = build_oidc_error_response ( & request, & e) ;
424- return request. into_response ( resp) ;
425- }
426- log:: error!( "Failed to process OIDC callback (attempt {redirect_count}). Refreshing oidc provider metadata, then redirecting to home page: {e:#}" ) ;
427- oidc_state. refresh_on_error ( & request) . await ;
428- let mut resp = build_auth_provider_redirect_response ( oidc_state, "/" ) . await ;
429- set_redirect_count_cookie ( & mut resp, redirect_count + 1 ) ;
430- request. into_response ( resp)
431- }
418+ Err ( e) => handle_oidc_callback_error ( oidc_state, request, e) . await ,
432419 }
433420}
434421
422+ async fn handle_oidc_callback_error (
423+ oidc_state : & OidcState ,
424+ request : ServiceRequest ,
425+ e : anyhow:: Error ,
426+ ) -> ServiceResponse {
427+ let redirect_count = get_redirect_count ( & request) ;
428+ if redirect_count >= MAX_OIDC_REDIRECTS {
429+ return handle_max_redirect_count_reached ( request, & e, redirect_count) ;
430+ }
431+ log:: error!(
432+ "Failed to process OIDC callback (attempt {redirect_count}). Refreshing oidc provider metadata, then redirecting to home page: {e:#}"
433+ ) ;
434+ oidc_state. refresh_on_error ( & request) . await ;
435+ let resp = build_auth_provider_redirect_response ( oidc_state, "/" , redirect_count) . await ;
436+ request. into_response ( resp)
437+ }
438+
439+ fn handle_max_redirect_count_reached (
440+ request : ServiceRequest ,
441+ e : & anyhow:: Error ,
442+ redirect_count : u8 ,
443+ ) -> ServiceResponse {
444+ log:: error!(
445+ "Failed to process OIDC callback after {redirect_count} attempts. \
446+ Stopping to avoid infinite redirections: {e:#}"
447+ ) ;
448+ let resp = build_oidc_error_response ( & request, e) ;
449+ request. into_response ( resp)
450+ }
451+
435452async fn handle_oidc_logout ( oidc_state : & OidcState , request : ServiceRequest ) -> ServiceResponse {
436453 match process_oidc_logout ( oidc_state, & request) . await {
437454 Ok ( response) => request. into_response ( response) ,
@@ -684,12 +701,23 @@ fn set_auth_cookie(response: &mut HttpResponse, id_token: &OidcToken) {
684701async fn build_auth_provider_redirect_response (
685702 oidc_state : & OidcState ,
686703 initial_url : & str ,
704+ redirect_count : u8 ,
687705) -> HttpResponse {
688706 let AuthUrl { url, params } = build_auth_url ( oidc_state) . await ;
689707 let tmp_login_flow_state_cookie = create_tmp_login_flow_state_cookie ( & params, initial_url) ;
708+ let redirect_count_cookie = Cookie :: build (
709+ SQLPAGE_OIDC_REDIRECT_COUNT_COOKIE ,
710+ ( redirect_count + 1 ) . to_string ( ) ,
711+ )
712+ . path ( "/" )
713+ . http_only ( true )
714+ . same_site ( actix_web:: cookie:: SameSite :: Lax )
715+ . max_age ( LOGIN_FLOW_STATE_COOKIE_EXPIRATION )
716+ . finish ( ) ;
690717 HttpResponse :: SeeOther ( )
691718 . append_header ( ( header:: LOCATION , url. to_string ( ) ) )
692719 . cookie ( tmp_login_flow_state_cookie)
720+ . cookie ( redirect_count_cookie)
693721 . body ( "Redirecting..." )
694722}
695723
@@ -706,16 +734,6 @@ fn get_redirect_count(request: &ServiceRequest) -> u8 {
706734 . unwrap_or ( 0 )
707735}
708736
709- fn set_redirect_count_cookie ( response : & mut HttpResponse , count : u8 ) {
710- let cookie = Cookie :: build ( SQLPAGE_OIDC_REDIRECT_COUNT_COOKIE , count. to_string ( ) )
711- . path ( "/" )
712- . http_only ( true )
713- . same_site ( actix_web:: cookie:: SameSite :: Lax )
714- . max_age ( LOGIN_FLOW_STATE_COOKIE_EXPIRATION )
715- . finish ( ) ;
716- response. add_cookie ( & cookie) . ok ( ) ;
717- }
718-
719737fn clear_redirect_count_cookie ( response : & mut HttpResponse ) {
720738 let cookie = Cookie :: build ( SQLPAGE_OIDC_REDIRECT_COUNT_COOKIE , "" )
721739 . path ( "/" )
0 commit comments