diff --git a/src/api/client/oidc/authorize.rs b/src/api/client/oidc/authorize.rs index f8a74f7b..5e767057 100644 --- a/src/api/client/oidc/authorize.rs +++ b/src/api/client/oidc/authorize.rs @@ -22,7 +22,7 @@ pub(crate) async fn authorize( Query(query): Query, oauth: OidcRequest, ) -> Result { - tracing::trace!("processing OAuth request: {query:?}"); + tracing::trace!("processing OAuth request: {query:#?}"); // Enforce MSC2964's restrictions on OAuth2 flow. let Ok(scope) = percent_decode_str(&query.scope).decode_utf8() else { return Err(err!(Request(Unknown("the scope could not be percent-decoded")))); @@ -50,6 +50,10 @@ pub(crate) async fn authorize( }, } // TODO register the device ID ? + tracing::debug!( + "submitting OIDC authorisation for token : {:#?}", + oauth.authorization_header().unwrap() + ); services .oidc diff --git a/src/api/client/oidc/login.rs b/src/api/client/oidc/login.rs index ca0d8b9a..78c2b922 100644 --- a/src/api/client/oidc/login.rs +++ b/src/api/client/oidc/login.rs @@ -19,6 +19,7 @@ pub(crate) async fn oidc_login( let query: LoginQuery = request.clone().try_into().map_err(|LoginError(err)| { err!(Request(InvalidParam("Cannot process login form. {err}"))) })?; + tracing::trace!("processing login query {:#?}", query.clone()); // Only accept local usernames. Mostly to simplify things at first. let user_id = UserId::parse_with_server_name(query.username.clone(), &services.config.server_name) @@ -35,10 +36,11 @@ pub(crate) async fn oidc_login( if verify_password(&query.password, &valid_hash).is_err() { return Err(err!(Request(InvalidParam("password does not match")))); } - tracing::info!("logging in: {user_id:?}"); let hostname = services.config.server_name.host(); let authorization_query: AuthorizationQuery = query.into(); + tracing::info!("logging in {user_id:?}"); + tracing::debug!("login {user_id} authorisation query : {authorization_query:#?}"); services .oidc @@ -46,5 +48,5 @@ pub(crate) async fn oidc_login( .with_solicitor(oidc_consent_form(hostname, &authorization_query)) .authorization_flow() .execute(request) - .map_err(|err| err!(Request(Unknown("authorization failed: {err:?}")))) + .map_err(|err| err!(Request(Unknown("authorisation failed: {err:?}")))) } diff --git a/src/api/client/oidc/register.rs b/src/api/client/oidc/register.rs index f4996d3c..6b752f5b 100644 --- a/src/api/client/oidc/register.rs +++ b/src/api/client/oidc/register.rs @@ -5,7 +5,7 @@ use reqwest::Url; use ruma::DeviceId; /// The required parameters to register a new client for OAuth2 application. -#[derive(serde::Deserialize, Clone)] +#[derive(serde::Deserialize, Clone, Debug)] pub(crate) struct ClientQuery { /// Human-readable name. client_name: String, @@ -32,7 +32,7 @@ pub(crate) struct ClientQuery { } /// A successful response that the client was registered. -#[derive(serde::Serialize)] +#[derive(serde::Serialize, Debug)] pub(crate) struct ClientResponse { client_id: String, client_name: String, @@ -58,6 +58,7 @@ pub(crate) async fn register_client( State(services): State, Json(client): Json, ) -> Result> { + tracing::trace!("processing OIDC device register request for client: {client:#?}"); let Some(redirect_uri) = client.redirect_uris.first().cloned() else { return Err(err!(Request(Unknown( "register request should contain at least a redirect_uri" @@ -77,8 +78,7 @@ pub(crate) async fn register_client( .parse() .expect("device ID should parse in Matrix scope"), ))?; - - Ok(Json(ClientResponse { + let client_response = ClientResponse { client_id: device_id.to_string(), client_name: client.client_name.clone(), client_uri: client.client_uri.clone(), @@ -90,5 +90,8 @@ pub(crate) async fn register_client( response_types: client.response_types.clone(), grant_types: client.grant_types.clone(), application_type: client.application_type, - })) + }; + tracing::debug!("OIDC device registered : {client_response:#?}"); + + Ok(Json(client_response)) } diff --git a/src/api/client/oidc/token.rs b/src/api/client/oidc/token.rs index 3301eedc..c2082318 100644 --- a/src/api/client/oidc/token.rs +++ b/src/api/client/oidc/token.rs @@ -11,6 +11,7 @@ pub(crate) async fn token( State(services): State, oauth: OidcRequest, ) -> Result { + tracing::trace!("processing OpenID token request {:#?}", oauth); let Some(body) = oauth.body() else { return Err(err!(Request(Unknown("OAuth request had an empty body")))); }; @@ -18,6 +19,7 @@ pub(crate) async fn token( .unique_value("grant_type") .map(|value| value.to_string()); let endpoint = services.oidc.endpoint(); + tracing::debug!("submitting OpenID token request for grant type {grant_type:?}"); match grant_type.as_deref() { | Some("authorization_code") => endpoint diff --git a/src/web/oidc/consent.rs b/src/web/oidc/consent.rs index ba95dc86..fbc2ce05 100644 --- a/src/web/oidc/consent.rs +++ b/src/web/oidc/consent.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use askama::Template; use axum::http::StatusCode; use oxide_auth::frontends::simple::request::Body; @@ -28,8 +29,8 @@ pub fn oidc_consent_form(hostname: &str, query: &AuthorizationQuery) -> OidcResp 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" => "fragment", - | _ => "query" + | "https" => Cow::Borrowed("fragment"), + | _ => Cow::Borrowed("query") }); let template = ConsentPageTemplate { nonce, @@ -42,7 +43,7 @@ fn consent_page(hostname: &str, query: &AuthorizationQuery, route: &str, nonce: code_challenge: &encode(query.code_challenge.as_str()), code_challenge_method: &encode(query.code_challenge_method.as_str()), response_type: &encode(query.response_type.as_str()), - response_mode: &encode(response_mode), + response_mode: &encode(response_mode.as_str()), }; template.render().expect("consent page render") diff --git a/src/web/oidc/login.rs b/src/web/oidc/login.rs index e8008710..60719f62 100644 --- a/src/web/oidc/login.rs +++ b/src/web/oidc/login.rs @@ -1,4 +1,4 @@ -use std::str::FromStr; +use std::{borrow::Cow, str::FromStr}; use askama::Template; use axum::http::StatusCode; @@ -65,8 +65,8 @@ impl TryFrom for LoginQuery { // 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" => "fragment", - | _ => "query" + | "https" => Cow::Borrowed("fragment"), + | _ => Cow::Borrowed("query") }); Ok(Self {