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::extract::State;
|
||||||
use axum_client_ip::InsecureClientIp;
|
use axum_client_ip::InsecureClientIp;
|
||||||
@@ -63,6 +63,10 @@ struct GrantCookie<'a> {
|
|||||||
|
|
||||||
static GRANT_SESSION_COOKIE: &str = "tuwunel_grant_session";
|
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(
|
#[tracing::instrument(
|
||||||
name = "sso_login",
|
name = "sso_login",
|
||||||
level = "debug",
|
level = "debug",
|
||||||
@@ -70,16 +74,47 @@ static GRANT_SESSION_COOKIE: &str = "tuwunel_grant_session";
|
|||||||
fields(%client),
|
fields(%client),
|
||||||
)]
|
)]
|
||||||
pub(crate) async fn sso_login_route(
|
pub(crate) async fn sso_login_route(
|
||||||
State(_services): State<crate::State>,
|
State(services): State<crate::State>,
|
||||||
InsecureClientIp(client): InsecureClientIp,
|
InsecureClientIp(client): InsecureClientIp,
|
||||||
_body: Ruma<sso_login::v3::Request>,
|
body: Ruma<sso_login::v3::Request>,
|
||||||
) -> Result<sso_login::v3::Response> {
|
) -> Result<sso_login::v3::Response> {
|
||||||
Err!(Request(NotImplemented(
|
if services.config.sso_custom_providers_page {
|
||||||
"sso_custom_providers_page has been enabled but this URL has not been overridden with \
|
return Err!(Request(NotImplemented(
|
||||||
any custom page listing the available providers..."
|
"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(
|
#[tracing::instrument(
|
||||||
name = "sso_login_with_provider",
|
name = "sso_login_with_provider",
|
||||||
level = "info",
|
level = "info",
|
||||||
@@ -95,7 +130,18 @@ pub(crate) async fn sso_login_with_provider_route(
|
|||||||
InsecureClientIp(client): InsecureClientIp,
|
InsecureClientIp(client): InsecureClientIp,
|
||||||
body: Ruma<sso_login_with_provider::v3::Request>,
|
body: Ruma<sso_login_with_provider::v3::Request>,
|
||||||
) -> Result<sso_login_with_provider::v3::Response> {
|
) -> 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 {
|
let Ok(redirect_url) = redirect_url.parse::<Url>() else {
|
||||||
return Err!(Request(InvalidParam("Invalid redirect_url")));
|
return Err!(Request(InvalidParam("Invalid redirect_url")));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2139,6 +2139,19 @@ pub struct Config {
|
|||||||
#[serde(default = "default_one_time_key_limit")]
|
#[serde(default = "default_one_time_key_limit")]
|
||||||
pub one_time_key_limit: usize,
|
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
|
/// 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
|
/// 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
|
/// sign-on" linking to the URL `/_matrix/client/v3/login/sso/redirect`. The
|
||||||
|
|||||||
@@ -1834,6 +1834,19 @@
|
|||||||
#
|
#
|
||||||
#one_time_key_limit = 256
|
#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
|
# 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
|
# 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
|
# sign-on" linking to the URL `/_matrix/client/v3/login/sso/redirect`. The
|
||||||
|
|||||||
Reference in New Issue
Block a user