@@ -496,25 +496,33 @@ pub struct LoginUrlQuery {
496496/// Generate URL to IdP login form. Optional `state` param is included in query
497497/// string if present, and will typically represent the URL to send the user
498498/// back to after successful login.
499+ // TODO this does not know anything about IdPs, and it should. When the user is
500+ // logged out and hits an auth-gated route, if there are multiple IdPs and we
501+ // don't known which one they want to use, we need to send them to a page that
502+ // will allow them to choose among discoverable IdPs. However, there may be ways
503+ // to give ourselves a hint about which one they want, for example, by storing
504+ // that info in a browser cookie when they log in. When their session ends, we
505+ // will not be able to look at the dead session to find the silo or IdP (well,
506+ // maybe we can but we probably shouldn't) but we can look at the cookie and
507+ // default to sending them to the IdP indicated (though if they don't want that
508+ // one we need to make sure they can get to a different one). If there is no
509+ // cookie, we send them to the selector page. In any case, none of this is done
510+ // here yet. We go to /spoof_login no matter what.
499511fn get_login_url ( state : Option < String > ) -> String {
500- // assume state is not URL encoded, so no risk of double encoding (dropshot
501- // decodes it on the way in)
512+ // assume state is not already URL encoded
502513 let query = match state {
503- Some ( state) if state. is_empty ( ) => None ,
504- Some ( state) => {
514+ Some ( state) if !state. is_empty ( ) => {
505515 serde_urlencoded:: to_string ( LoginUrlQuery { state : Some ( state) } )
506- . ok ( ) // in the hard-to-imagine event it's not serializable, no query
516+ . ok ( ) // in the strange event it's not serializable, no query
507517 }
508- None => None ,
518+ _ => None ,
509519 } ;
510520 // Once we have IdP integration, this will be a URL for the IdP login page.
511521 // For now we point to our own placeholder login page.
512- let mut url = "/spoof_login" . to_string ( ) ;
513- if let Some ( query) = query {
514- url. push ( '?' ) ;
515- url. push_str ( query. as_str ( ) ) ;
522+ match query {
523+ Some ( query) => format ! ( "/spoof_login?{query}" ) ,
524+ None => "/spoof_login" . to_string ( ) ,
516525 }
517- url
518526}
519527
520528/// Redirect to IdP login URL
@@ -571,11 +579,11 @@ pub async fn console_index_or_login_redirect(
571579 // otherwise redirect to idp
572580
573581 // put the current URI in the query string to redirect back to after login
574- let uri = rqctx. request . lock ( ) . await . uri ( ) . clone ( ) ;
582+ let uri = rqctx. request . lock ( ) . await . uri ( ) . to_string ( ) ;
575583
576584 Ok ( Response :: builder ( )
577585 . status ( StatusCode :: FOUND )
578- . header ( http:: header:: LOCATION , get_login_url ( Some ( uri. to_string ( ) ) ) )
586+ . header ( http:: header:: LOCATION , get_login_url ( Some ( uri) ) )
579587 . body ( "" . into ( ) ) ?)
580588}
581589
0 commit comments