From 696adfc90be44c2ce5584ae277690bbc9ec7cef8 Mon Sep 17 00:00:00 2001 From: lafleur Date: Sat, 9 Aug 2025 01:03:44 +0200 Subject: [PATCH] OIDC: make response_mode optional Fractal omits the `response_mode` field when in an auth flow (its value must be the literal "S256", so it's mainly here for OIDC compliance I guess). Accepting this lets it proceed to the next authentication step. --- src/web/oidc/consent.rs | 7 +------ src/web/oidc/login.rs | 15 +++------------ 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/web/oidc/consent.rs b/src/web/oidc/consent.rs index 311117e0..5967ed8f 100644 --- a/src/web/oidc/consent.rs +++ b/src/web/oidc/consent.rs @@ -1,4 +1,3 @@ -use std::borrow::Cow; use askama::Template; use axum::http::StatusCode; use oxide_auth::frontends::simple::request::Body; @@ -27,11 +26,7 @@ pub fn oidc_consent_form(hostname: &str, query: &AuthorizationQuery) -> OidcResp /// Render the html contents of the user consent page. fn consent_page(hostname: &str, query: &AuthorizationQuery, route: &str, nonce: &str) -> String { - let response_mode = &query.response_mode.clone() - .unwrap_or_else(|| match query.redirect_uri.scheme() { - | "https" => Cow::Borrowed("fragment"), - | _ => Cow::Borrowed("query") - }); + let response_mode = &query.response_mode.clone().unwrap_or("fragment".to_string()); let template = ConsentPageTemplate { nonce, hostname, diff --git a/src/web/oidc/login.rs b/src/web/oidc/login.rs index 9c36268a..c221a310 100644 --- a/src/web/oidc/login.rs +++ b/src/web/oidc/login.rs @@ -62,13 +62,9 @@ impl TryFrom for LoginQuery { let Ok(redirect_uri) = Url::from_str(&redirect_uri) else { return Err(LoginError("invalid field: redirect_uri".to_owned())); }; - // response_mode is not strictly needed : its value defaults to "fragment" + // response_mode is not strictly needed : it must be the literal "fragment" // when over https. It's required by the spec but Fractal doesn't provide it. - let response_mode = body.unique_value("response_mode") - .unwrap_or_else(|| match redirect_uri.scheme() { - | "https" => Cow::Borrowed("fragment"), - | _ => Cow::Borrowed("query") - }); + let response_mode = body.unique_value("response_mode").unwrap_or(Cow::Borrowed("fragment")); let client_secret = body.unique_value("client_secret").map(|s| s.to_string()); Ok(Self { @@ -108,12 +104,7 @@ pub fn oidc_login_form(hostname: &str, query: &AuthorizationQuery) -> OidcRespon /// Render the html contents of the login page. fn login_page(hostname: &str, query: &AuthorizationQuery, route: &str, nonce: &str) -> String { - let response_mode = &query.response_mode - .clone() - .unwrap_or_else(|| match query.redirect_uri.scheme() { - | "https" => "fragment".to_string(), - | _ => "query".to_string() - }); + let response_mode = &query.response_mode.clone().unwrap_or("fragment".to_string()); let template = LoginPageTemplate { nonce, hostname,