Skip to main content

arminius_server_client/handlers/
auth.rs

1// SPDX-FileCopyrightText: 2025 BWI GmbH
2//
3// SPDX-License-Identifier: Apache-2.0
4
5//! Auth component
6
7mod tests;
8
9use arminius_lib_component::{
10	Component, ServerState,
11	error::{InternalServerError, MatrixApiError, ResultExt as _},
12};
13use arminius_lib_reqwest::setup_insecure_reqwest_client;
14use axum::{Json, Router, extract::State, routing::get};
15use reqwest::StatusCode;
16use ruma::api::error::ErrorKind;
17
18/// Errors returned on the auth_metadata endpoint
19#[derive(MatrixApiError, thiserror::Error, Debug)]
20enum AuthMetadataError {
21	/// Unrecoverable error.
22	/// See <https://bundesmessenger.gitlab.io/backend/neo/arminius/arminius/03-development/errors.html#unrecoverable-errors>
23	#[error(transparent)]
24	InternalServerError(#[from] InternalServerError),
25	/// A 404 error for when OIDC is not configured.
26	///
27	/// Error message taken straight from the spec for the endpoint.
28	#[matrix_api_error(status_code = StatusCode::NOT_FOUND, error_kind = ErrorKind::Unrecognized)]
29	#[error("Legacy authentication is in use on this homeserver.")]
30	NoAuthData,
31}
32
33/// Handler for `GET /_matrix/client/v1/auth_metadata` (See <https://spec.matrix.org/unstable/client-server-api/#get_matrixclientv1auth_metadata>).
34/// For compatibility, this is also exposed under the old experimental endpoint
35/// `GET /_matrix/client/unstable/org.matrix.msc2965/auth_metadata`.
36///
37/// NOTE: Ruma has not implemented this endpoint yet. The Matrix OpenAPI
38/// specification of this endpoint (`getAuthMetadata`, see
39/// <https://github.com/matrix-org/matrix-spec/blob/2aacc1feda4bd949d1148755ab724718f03c4a3a/data/api/client-server/oauth_server_metadata.yaml#L48>)
40/// is missing some response fields that are required by Element for successful
41/// login. Therefore, we just pass the entire metadata as we got it from the
42/// upstream IdP.
43async fn auth_metadata(
44	state: State<ServerState>,
45) -> Result<Json<serde_json::Map<String, serde_json::Value>>, AuthMetadataError> {
46	let Some(openid_configuration_url) = state.config.oidc_well_known.as_ref() else {
47		return Err(AuthMetadataError::NoAuthData);
48	};
49
50	let req = setup_insecure_reqwest_client(&state.config)
51		.unrecoverable_error("Could not set up Reqwest client. Invalid proxy setup?")?
52		.get(openid_configuration_url.clone());
53	let resp = req.send().await.unrecoverable_error("OIDC well known request failed")?;
54	let auth_metadata = resp.json().await.unrecoverable_error("OIDC well known response error")?;
55
56	Ok(Json(auth_metadata))
57}
58
59/// Component implementing endpoints for account management
60#[derive(Debug)]
61pub struct AuthComponent;
62
63impl Component for AuthComponent {
64	fn router() -> Router<ServerState> {
65		Router::new()
66			.route("/_matrix/client/v1/auth_metadata", get(auth_metadata))
67			.route("/_matrix/client/unstable/org.matrix.msc2965/auth_metadata", get(auth_metadata))
68	}
69}