Add sso_default_provider_id option and defaulting behavior.
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use std::{borrow::Cow, time::Duration};
|
||||
use std::{borrow::Cow, net::IpAddr, time::Duration};
|
||||
|
||||
use axum::extract::State;
|
||||
use axum_client_ip::InsecureClientIp;
|
||||
@@ -63,6 +63,10 @@ struct GrantCookie<'a> {
|
||||
|
||||
static GRANT_SESSION_COOKIE: &str = "tuwunel_grant_session";
|
||||
|
||||
/// # `GET /_matrix/client/v3/login/sso/redirect`
|
||||
///
|
||||
/// A web-based Matrix client should instruct the user’s browser to navigate to
|
||||
/// this endpoint in order to log in via SSO.
|
||||
#[tracing::instrument(
|
||||
name = "sso_login",
|
||||
level = "debug",
|
||||
@@ -70,16 +74,47 @@ static GRANT_SESSION_COOKIE: &str = "tuwunel_grant_session";
|
||||
fields(%client),
|
||||
)]
|
||||
pub(crate) async fn sso_login_route(
|
||||
State(_services): State<crate::State>,
|
||||
State(services): State<crate::State>,
|
||||
InsecureClientIp(client): InsecureClientIp,
|
||||
_body: Ruma<sso_login::v3::Request>,
|
||||
body: Ruma<sso_login::v3::Request>,
|
||||
) -> Result<sso_login::v3::Response> {
|
||||
Err!(Request(NotImplemented(
|
||||
"sso_custom_providers_page has been enabled but this URL has not been overridden with \
|
||||
any custom page listing the available providers..."
|
||||
)))
|
||||
if services.config.sso_custom_providers_page {
|
||||
return Err!(Request(NotImplemented(
|
||||
"sso_custom_providers_page has been enabled but this URL has not been overridden \
|
||||
with any custom page listing the available providers..."
|
||||
)));
|
||||
}
|
||||
|
||||
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
|
||||
.config
|
||||
.identity_provider
|
||||
.iter()
|
||||
.next()
|
||||
.map(|idp| idp.client_id.clone())
|
||||
.unwrap_or_default();
|
||||
|
||||
let redirect_url = body.body.redirect_url;
|
||||
|
||||
handle_sso_login(&services, &client, idp_id, redirect_url)
|
||||
.map_ok(|response| sso_login::v3::Response {
|
||||
location: response.location,
|
||||
cookie: response.cookie,
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
/// # `GET /_matrix/client/v3/login/sso/redirect/{idpId}`
|
||||
///
|
||||
/// This endpoint is the same as /login/sso/redirect, though with an IdP ID from
|
||||
/// the original identity_providers array to inform the server of which IdP the
|
||||
/// client/user would like to continue with.
|
||||
#[tracing::instrument(
|
||||
name = "sso_login_with_provider",
|
||||
level = "info",
|
||||
@@ -95,7 +130,18 @@ pub(crate) async fn sso_login_with_provider_route(
|
||||
InsecureClientIp(client): InsecureClientIp,
|
||||
body: Ruma<sso_login_with_provider::v3::Request>,
|
||||
) -> Result<sso_login_with_provider::v3::Response> {
|
||||
let sso_login_with_provider::v3::Request { idp_id, redirect_url } = body.body;
|
||||
let idp_id = body.body.idp_id;
|
||||
let redirect_url = body.body.redirect_url;
|
||||
|
||||
handle_sso_login(&services, &client, idp_id, redirect_url).await
|
||||
}
|
||||
|
||||
async fn handle_sso_login(
|
||||
services: &Services,
|
||||
_client: &IpAddr,
|
||||
idp_id: String,
|
||||
redirect_url: String,
|
||||
) -> Result<sso_login_with_provider::v3::Response> {
|
||||
let Ok(redirect_url) = redirect_url.parse::<Url>() else {
|
||||
return Err!(Request(InvalidParam("Invalid redirect_url")));
|
||||
};
|
||||
|
||||
@@ -2139,6 +2139,19 @@ 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
|
||||
|
||||
@@ -1834,6 +1834,19 @@
|
||||
#
|
||||
#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
|
||||
|
||||
Reference in New Issue
Block a user