From 98f5ea203b4c31706a366c2560d58dd4f9476448 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Sun, 18 Jan 2026 02:20:04 +0000 Subject: [PATCH] Add simpler option to specify default identity_provider. Signed-off-by: Jason Volk --- src/api/client/session/sso.rs | 18 +++++++--------- src/core/config/check.rs | 39 ++++++++++++++++++++++++++++++++++- src/core/config/mod.rs | 27 ++++++++++++------------ tuwunel-example.toml | 27 ++++++++++++------------ 4 files changed, 73 insertions(+), 38 deletions(-) diff --git a/src/api/client/session/sso.rs b/src/api/client/session/sso.rs index d71eeb8c..769cd627 100644 --- a/src/api/client/session/sso.rs +++ b/src/api/client/session/sso.rs @@ -14,6 +14,7 @@ use ruma::{ use serde::{Deserialize, Serialize}; use tuwunel_core::{ Err, Result, at, + config::IdentityProvider, debug::INFO_SPAN_LEVEL, debug_info, debug_warn, err, info, utils, utils::{ @@ -85,24 +86,19 @@ pub(crate) async fn sso_login_route( ))); } - if services.config.identity_provider.len() > 1 { - return Err!(Config( - "sso_default_provider_id", - "This must be set when using more than one identity provider." - )); - } - - let idp_id = services + let default_idp_id = services .config .identity_provider .iter() - .next() - .map(|idp| idp.client_id.clone()) + .find(|idp| idp.default) + .or_else(|| services.config.identity_provider.iter().next()) + .map(IdentityProvider::id) + .map(ToOwned::to_owned) .unwrap_or_default(); let redirect_url = body.body.redirect_url; - handle_sso_login(&services, &client, idp_id, redirect_url) + handle_sso_login(&services, &client, default_idp_id, redirect_url) .map_ok(|response| sso_login::v3::Response { location: response.location, cookie: response.cookie, diff --git a/src/core/config/check.rs b/src/core/config/check.rs index fe0a6a75..a5465940 100644 --- a/src/core/config/check.rs +++ b/src/core/config/check.rs @@ -3,7 +3,7 @@ use std::env::consts::OS; use either::Either; use figment::Figment; -use super::DEPRECATED_KEYS; +use super::{DEPRECATED_KEYS, IdentityProvider}; use crate::{Config, Err, Result, Server, debug, debug_info, debug_warn, error, warn}; /// Performs check() with additional checks specific to reloading old config @@ -317,6 +317,43 @@ pub fn check(config: &Config) -> Result { } } + if config + .identity_provider + .iter() + .filter(|idp| idp.default) + .count() + .gt(&1) + { + return Err!(Config( + "identity_provider.default", + "More than one identity_provider is configured with `default = true`. Only one can \ + be set to default.", + )); + } + + if !config.sso_custom_providers_page + && config.identity_provider.len() > 1 + && config + .identity_provider + .iter() + .filter(|idp| idp.default) + .count() + .eq(&0) + { + let default = config + .identity_provider + .iter() + .next() + .map(IdentityProvider::id) + .expect("Check at least one provider is configured to reach here"); + + warn!( + "More than one identity_provider has been configured without any default selected. \ + To prevent this warning set `default = true` for one provider. Considering \ + {default} the default for now..." + ); + } + Ok(()) } diff --git a/src/core/config/mod.rs b/src/core/config/mod.rs index fd6bf55f..4ae03b96 100644 --- a/src/core/config/mod.rs +++ b/src/core/config/mod.rs @@ -2160,19 +2160,6 @@ pub struct Config { #[serde(default = "default_one_time_key_limit")] pub one_time_key_limit: usize, - /// This option is relevant when more than one identity_provider has been - /// configured and `sso_custom_providers_page` is false. Set this option to - /// the `client_id` of the provider to use for requests to - /// `/_matrix/client/v3/login/sso/redirect` (the url lacks a `client_id`). - /// - /// This *must* be configured for some clients (e.g. fluffychat) to work - /// properly when the above conditions require it. - /// - /// When only one identity_provider is configured that will be used as the - /// default and this does not have to be set. - #[serde(default)] - pub sso_default_provider_id: String, - /// Setting this option to true replaces the list of identity providers on /// the client's login screen with a single button "Sign in with single /// sign-on" linking to the URL `/_matrix/client/v3/login/sso/redirect`. The @@ -2570,6 +2557,20 @@ pub struct IdentityProvider { /// `` is the same one configured for this provider above. pub callback_url: Option, + /// When more than one identity_provider has been configured and + /// `sso_custom_providers_page` is false this will determine the results + /// for the `/_matrix/client/v3/login/sso/redirect` endpoint (note the url + /// lacks a trailing `client_id`). + /// + /// When only one identity_provider is configured it will be interpreted + /// as the default and this does not have to be set. Otherwise a default + /// *must* be selected for some clients (e.g. fluffychat) to work properly + /// when the above conditions require it. For compatibility if not set a + /// warning will be logged on startup and the first provider listed will be + /// considered the default. + #[serde(default)] + pub default: bool, + /// Optional display-name for this provider instance seen on the login page /// by users. It defaults to `brand`. When configuring multiple providers /// using the same `brand` this can be set to distinguish them. diff --git a/tuwunel-example.toml b/tuwunel-example.toml index 424df2f9..b76a050f 100644 --- a/tuwunel-example.toml +++ b/tuwunel-example.toml @@ -1852,19 +1852,6 @@ # #one_time_key_limit = 256 -# This option is relevant when more than one identity_provider has been -# configured and `sso_custom_providers_page` is false. Set this option to -# the `client_id` of the provider to use for requests to -# `/_matrix/client/v3/login/sso/redirect` (the url lacks a `client_id`). -# -# This *must* be configured for some clients (e.g. fluffychat) to work -# properly when the above conditions require it. -# -# When only one identity_provider is configured that will be used as the -# default and this does not have to be set. -# -#sso_default_provider_id = false - # Setting this option to true replaces the list of identity providers on # the client's login screen with a single button "Sign in with single # sign-on" linking to the URL `/_matrix/client/v3/login/sso/redirect`. The @@ -2190,6 +2177,20 @@ # #callback_url = +# When more than one identity_provider has been configured and +# `sso_custom_providers_page` is false this will determine the results +# for the `/_matrix/client/v3/login/sso/redirect` endpoint (note the url +# lacks a trailing `client_id`). +# +# When only one identity_provider is configured it will be interpreted +# as the default and this does not have to be set. Otherwise a default +# *must* be selected for some clients (e.g. fluffychat) to work properly +# when the above conditions require it. For compatibility if not set a +# warning will be logged on startup and the first provider listed will be +# considered the default. +# +#default = false + # Optional display-name for this provider instance seen on the login page # by users. It defaults to `brand`. When configuring multiple providers # using the same `brand` this can be set to distinguish them.