pub async fn oauth_callback(
    settings: Arc<Settings>,
    login_query: LoginQuery,
    headers: HeaderMap,
) -> Result<impl warp::Reply, warp::Rejection> {
    // Verify that login is allowed and this is a legitimate reply from the openid provider.
    if !settings.permit_login {
        warn!("Invalid login attempt (login not permitted)");
        return Err(warp::reject());
    }
    let (expected_state, redirect_url, origin) =
        match validate_login_cookie(settings.clone(), &headers) {
            Some(validated) => validated,
            None => {
                error!("Login cookie validation failed");
                return Ok(Response::builder()
                    .status(StatusCode::UNAUTHORIZED)
                    .body("Unauthorized"));
            }
        };
    if login_query.state != Some(expected_state) {
        error!("Login state mismatch");
        return Ok(Response::builder()
            .status(StatusCode::UNAUTHORIZED)
            .body("Unauthorized"));
    }

    // Workaround: The redirect_uri might not be a constant as it might
    // depend on the X-Forwarded-Host/X-Forwarded-Proto headers
    let mut openid_client = settings.openid_client.clone();

    openid_client.redirect_uri = Some(redirect_url);

    // Exchange the authcode to an actual set of tokens
    match openid_client.request_token(&login_query.code).await {
        Ok(bearer) => {
            // If successful: Store the tokens in their corresponding cookies.
            let mut response = Response::builder()
                .status(StatusCode::MOVED_PERMANENTLY)
                .header(header::LOCATION, origin);
            if let Some(refresh_token) = bearer.refresh_token {
                response = add_refresh_cookie(settings.clone(), &refresh_token, response);
            }
            response = add_auth_cookie(
                settings.clone(),
                bearer.id_token.unwrap_or(bearer.access_token),
                bearer.expires,
                response,
            );

            let mut login_cookie = cookie::Cookie::build(&settings.login_cookie, "")
                .http_only(true)
                .path(&settings.cookie_path)
                .secure(settings.cookie_secure)
                .max_age(time::Duration::seconds(0));
            if let Some(cookie_domain) = &settings.cookie_domain {
                login_cookie = login_cookie.domain(cookie_domain);
            }
            response = response.header(header::SET_COOKIE, login_cookie.finish().to_string());

            Ok(response.body(""))
        }
        Err(err) => {
            error!("login error in call: {}", err);

            Ok(Response::builder()
                .status(StatusCode::UNAUTHORIZED)
                .body("Unauthorized"))
        }
    }
}
// Handle an oauth callback, i.e. complete the openid login flow.
Handle an oauth callback, i.e. complete the openid login flow.
Handle an oauth callback i . e . complete the openid login flow .
pub async fn oauth_callback(
    settings: Arc<Settings>,
    login_query: LoginQuery,
    headers: HeaderMap,
) -> Result<impl warp::Reply, warp::Rejection> {
    // Verify that login is allowed and this is a legitimate reply from the openid provider.
    if !settings.permit_login {
        warn!("Invalid login attempt (login not permitted)");
        return Err(warp::reject());
    }
    let (expected_state, redirect_url, origin) =
        match validate_login_cookie(settings.clone(), &headers) {
            Some(validated) => validated,
            None => {
                error!("Login cookie validation failed");
                return Ok(Response::builder()
                    .status(StatusCode::UNAUTHORIZED)
                    .body("Unauthorized"));
            }
        };
    if login_query.state != Some(expected_state) {
        error!("Login state mismatch");
        return Ok(Response::builder()
            .status(StatusCode::UNAUTHORIZED)
            .body("Unauthorized"));
    }
    // Workaround: The redirect_uri might not be a constant as it might
    // depend on the X-Forwarded-Host/X-Forwarded-Proto headers
    let mut openid_client = settings.openid_client.clone();
    openid_client.redirect_uri = Some(redirect_url);
    // Exchange the authcode to an actual set of tokens
    match openid_client.request_token(&login_query.code).await {
        Ok(bearer) => {
            // If successful: Store the tokens in their corresponding cookies.
            let mut response = Response::builder()
                .status(StatusCode::MOVED_PERMANENTLY)
                .header(header::LOCATION, origin);
            if let Some(refresh_token) = bearer.refresh_token {
                response = add_refresh_cookie(settings.clone(), &refresh_token, response);
            }
            response = add_auth_cookie(
                settings.clone(),
                bearer.id_token.unwrap_or(bearer.access_token),
                bearer.expires,
                response,
            );
            let mut login_cookie = cookie::Cookie::build(&settings.login_cookie, "")
                .http_only(true)
                .path(&settings.cookie_path)
                .secure(settings.cookie_secure)
                .max_age(time::Duration::seconds(0));
            if let Some(cookie_domain) = &settings.cookie_domain {
                login_cookie = login_cookie.domain(cookie_domain);
            }
            response = response.header(header::SET_COOKIE, login_cookie.finish().to_string());
            Ok(response.body(""))
        }
        Err(err) => {
            error!("login error in call: {}", err);
            Ok(Response::builder()
                .status(StatusCode::UNAUTHORIZED)
                .body("Unauthorized"))
        }
    }
}
pub async fn oauth_callback ( settings : Arc < Settings > , login_query : LoginQuery , headers : HeaderMap , ) -> Result < impl warp :: Reply , warp :: Rejection > { // Verify that login is allowed and this is a legitimate reply from the openid provider. if ! settings . permit_login { warn ! ( " " ) ; return Err ( warp :: reject ( ) ) ; } let ( expected_state , redirect_url , origin ) = match validate_login_cookie ( settings . clone ( ) , & headers ) { Some ( validated ) => validated , None => { error ! ( " " ) ; return Ok ( Response :: builder ( ) . status ( StatusCode :: UNAUTHORIZED ) . body ( " " ) ) ; } } ; if login_query . state != Some ( expected_state ) { error ! ( " " ) ; return Ok ( Response :: builder ( ) . status ( StatusCode :: UNAUTHORIZED ) . body ( " " ) ) ; } // Workaround: The redirect_uri might not be a constant as it might // depend on the X-Forwarded-Host/X-Forwarded-Proto headers let mut openid_client = settings . openid_client . clone ( ) ; openid_client . redirect_uri = Some ( redirect_url ) ; // Exchange the authcode to an actual set of tokens match openid_client . request_token ( & login_query . code ) . await { Ok ( bearer ) => { // If successful: Store the tokens in their corresponding cookies. let mut response = Response :: builder ( ) . status ( StatusCode :: MOVED_PERMANENTLY ) . header ( header :: LOCATION , origin ) ; if let Some ( refresh_token ) = bearer . refresh_token { response = add_refresh_cookie ( settings . clone ( ) , & refresh_token , response ) ; } response = add_auth_cookie ( settings . clone ( ) , bearer . id_token . unwrap_or ( bearer . access_token ) , bearer . expires , response , ) ; let mut login_cookie = cookie :: Cookie :: build ( & settings . login_cookie , " " ) . http_only ( true ) . path ( & settings . cookie_path ) . secure ( settings . cookie_secure ) . max_age ( time :: Duration :: seconds ( 0 ) ) ; if let Some ( cookie_domain ) = & settings . cookie_domain { login_cookie = login_cookie . domain ( cookie_domain ) ; } response = response . header ( header :: SET_COOKIE , login_cookie . finish ( ) . to_string ( ) ) ; Ok ( response . body ( " " ) ) } Err ( err ) => { error ! ( " " err ) ; Ok ( Response :: builder ( ) . status ( StatusCode :: UNAUTHORIZED ) . body ( " " ) ) } } }
Handle an oauth callback, i.e.
Handle an oauth callback i . e .
settings
Arc<Settings>
login_query
LoginQuery
headers
HeaderMap
settings
Arc<Settings>
login_query
LoginQuery
headers
HeaderMap