tuwunel_core/config/
well_known.rs1use std::collections::BTreeMap;
7
8use ruma::api::{
9 client::{
10 discovery::discover_support::Contact,
11 rtc::RtcTransport,
12 uiaa::{LoginTermsParams, PolicyDefinition, PolicyTranslation},
13 },
14 identity_service::tos::get_terms_of_service::v2::{LocalizedPolicy, Policies},
15};
16use tuwunel_macros::implement;
17
18use crate::{Result, err, error::inspect_log};
19
20#[implement(super::WellKnownConfig)]
25pub fn get_contacts(&self) -> Vec<Contact> {
26 let single_contact = self.support_role.clone().map(|role| Contact {
27 role,
28 email_address: self.support_email.clone(),
29 matrix_id: self.support_mxid.clone(),
30 pgp_key: self.support_pgp_key.clone(),
31 });
32
33 let contacts = self
34 .support_contact
35 .clone()
36 .into_values()
37 .map(Into::into);
38
39 contacts.chain(single_contact).collect()
40}
41
42#[implement(super::WellKnownConfig)]
47#[must_use]
48pub fn get_policies(&self) -> BTreeMap<String, Policies> {
49 self.support_policy
50 .iter()
51 .map(|(id, policy)| {
52 let localized = policy
53 .policy_translation
54 .iter()
55 .map(|(language, translation)| {
56 (language.clone(), LocalizedPolicy::from(translation.clone()))
57 })
58 .collect();
59
60 (id.clone(), Policies {
61 version: policy.version.clone(),
62 localized,
63 })
64 })
65 .collect()
66}
67
68#[implement(super::Config)]
73#[must_use]
74pub fn login_terms_params(&self) -> Option<LoginTermsParams> {
75 let policies: BTreeMap<_, _> = self
76 .registration_terms
77 .iter()
78 .map(|(id, policy)| {
79 let translations = policy
80 .translations
81 .iter()
82 .map(|(language, translation)| {
83 let translation = PolicyTranslation::new(
84 translation.name.clone(),
85 translation.url.to_string(),
86 );
87
88 (language.clone(), translation)
89 })
90 .collect();
91
92 (id.clone(), PolicyDefinition::new(policy.version.clone(), translations))
93 })
94 .collect();
95
96 (!policies.is_empty()).then(|| LoginTermsParams::new(policies))
97}
98
99#[implement(super::WellKnownConfig)]
103pub fn get_transports(&self) -> Result<Vec<RtcTransport>> {
104 let custom = self.rtc_transports.iter().map(|item| {
105 let mut data = item
106 .as_object()
107 .cloned()
108 .ok_or_else(|| err!("`rtc_transport` is not a valid object"))?;
109
110 let transport_type = data
111 .remove("type")
112 .and_then(|v| v.as_str().map(str::to_owned))
113 .ok_or_else(|| err!("`type` is not a valid string"))?;
114
115 RtcTransport::new(&transport_type, data).map_err(|e| {
116 err!(Config("global.well_known.rtc_transports", "Malformed value(s): {e:?}"))
117 })
118 });
119
120 let livekit_url = self
121 .livekit_url
122 .iter()
123 .cloned()
124 .map(|url| Ok(RtcTransport::livekit(url)));
125
126 custom
127 .chain(livekit_url)
128 .collect::<Result<Vec<_>>>()
129 .inspect_err(inspect_log)
130}