tuwunel_core/config/
well_known.rs1use 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#[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}