Skip to main content

tuwunel_core/config/
well_known.rs

1use std::collections::BTreeMap;
2
3use ruma::api::{
4	client::{
5		discovery::discover_support::Contact,
6		rtc::RtcTransport,
7		uiaa::{LoginTermsParams, PolicyDefinition, PolicyTranslation},
8	},
9	identity_service::tos::get_terms_of_service::v2::{LocalizedPolicy, Policies},
10};
11use tuwunel_macros::implement;
12
13use crate::{Result, err, error::inspect_log};
14
15#[implement(super::WellKnownConfig)]
16pub fn get_contacts(&self) -> Vec<Contact> {
17	let single_contact = self.support_role.clone().map(|role| Contact {
18		role,
19		email_address: self.support_email.clone(),
20		matrix_id: self.support_mxid.clone(),
21		pgp_key: self.support_pgp_key.clone(),
22	});
23
24	let contacts = self
25		.support_contact
26		.clone()
27		.into_values()
28		.map(Into::into);
29
30	contacts.chain(single_contact).collect()
31}
32
33#[implement(super::WellKnownConfig)]
34#[must_use]
35pub fn get_policies(&self) -> BTreeMap<String, Policies> {
36	self.support_policy
37		.iter()
38		.map(|(id, policy)| {
39			let localized = policy
40				.policy_translation
41				.iter()
42				.map(|(language, translation)| {
43					(language.clone(), LocalizedPolicy::from(translation.clone()))
44				})
45				.collect();
46
47			(id.clone(), Policies {
48				version: policy.version.clone(),
49				localized,
50			})
51		})
52		.collect()
53}
54
55#[implement(super::Config)]
56#[must_use]
57pub fn login_terms_params(&self) -> Option<LoginTermsParams> {
58	let policies: BTreeMap<_, _> = self
59		.registration_terms
60		.iter()
61		.map(|(id, policy)| {
62			let translations = policy
63				.translations
64				.iter()
65				.map(|(language, translation)| {
66					let translation = PolicyTranslation::new(
67						translation.name.clone(),
68						translation.url.to_string(),
69					);
70
71					(language.clone(), translation)
72				})
73				.collect();
74
75			(id.clone(), PolicyDefinition::new(policy.version.clone(), translations))
76		})
77		.collect();
78
79	(!policies.is_empty()).then(|| LoginTermsParams::new(policies))
80}
81
82/// Build the configured RTC transports as `RtcTransport` values, the typed
83/// form shared between `.well-known/matrix/client.rtc_foci` and the
84/// `/rtc/transports` endpoint.
85#[implement(super::WellKnownConfig)]
86pub fn get_transports(&self) -> Result<Vec<RtcTransport>> {
87	let custom = self.rtc_transports.iter().map(|item| {
88		let mut data = item
89			.as_object()
90			.cloned()
91			.ok_or_else(|| err!("`rtc_transport` is not a valid object"))?;
92
93		let transport_type = data
94			.remove("type")
95			.and_then(|v| v.as_str().map(str::to_owned))
96			.ok_or_else(|| err!("`type` is not a valid string"))?;
97
98		RtcTransport::new(&transport_type, data).map_err(|e| {
99			err!(Config("global.well_known.rtc_transports", "Malformed value(s): {e:?}"))
100		})
101	});
102
103	let livekit_url = self
104		.livekit_url
105		.iter()
106		.cloned()
107		.map(|url| Ok(RtcTransport::livekit(url)));
108
109	custom
110		.chain(livekit_url)
111		.collect::<Result<Vec<_>>>()
112		.inspect_err(inspect_log)
113}