Add simpler option to specify default identity_provider.

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk
2026-01-18 02:20:04 +00:00
parent 85ac256786
commit 98f5ea203b
4 changed files with 73 additions and 38 deletions

View File

@@ -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,

View File

@@ -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(())
}

View File

@@ -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 {
/// `<client_id>` is the same one configured for this provider above.
pub callback_url: Option<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.
#[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.

View File

@@ -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.