Skip to main content

tuwunel_service/globals/
mod.rs

1mod data;
2
3use std::{ops::Range, sync::Arc};
4
5pub use data::Data;
6use ruma::{OwnedUserId, RoomAliasId, ServerName, UserId};
7use tuwunel_core::{
8	Result, Server, err,
9	utils::{Secret, resolve_secret},
10};
11
12use crate::service;
13
14pub struct Service {
15	pub db: Data,
16	server: Arc<Server>,
17
18	pub server_user: OwnedUserId,
19}
20
21impl crate::Service for Service {
22	fn build(args: &crate::Args<'_>) -> Result<Arc<Self>> {
23		let db = Data::new(args);
24
25		Ok(Arc::new(Self {
26			db,
27			server: args.server.clone(),
28			server_user: UserId::parse_with_server_name(
29				String::from("conduit"),
30				&args.server.name,
31			)
32			.expect("@conduit:server_name is valid"),
33		}))
34	}
35
36	fn name(&self) -> &str { service::make_name(std::module_path!()) }
37}
38
39impl Service {
40	#[tracing::instrument(
41		level = "trace",
42		skip_all,
43		ret,
44		fields(pending = ?self.pending_count()),
45	)]
46	pub async fn wait_pending(&self) -> Result<u64> { self.db.wait_pending().await }
47
48	#[tracing::instrument(
49		level = "trace",
50		skip_all,
51		ret,
52		fields(pending = ?self.pending_count()),
53	)]
54	pub async fn wait_count(&self, count: &u64) -> Result<u64> { self.db.wait_count(count).await }
55
56	#[tracing::instrument(
57		level = "debug",
58		skip_all,
59		fields(pending = ?self.pending_count()),
60	)]
61	#[must_use]
62	pub fn next_count(&self) -> data::Permit { self.db.next_count() }
63
64	#[must_use]
65	pub fn current_count(&self) -> u64 { self.db.current_count() }
66
67	#[must_use]
68	pub fn pending_count(&self) -> Range<u64> { self.db.pending_count() }
69
70	#[inline]
71	#[must_use]
72	pub fn server_name(&self) -> &ServerName { self.server.name.as_ref() }
73
74	/// checks if `user_id` is local to us via server_name comparison
75	#[inline]
76	#[must_use]
77	pub fn user_is_local(&self, user_id: &UserId) -> bool {
78		self.server_is_ours(user_id.server_name())
79	}
80
81	#[inline]
82	#[must_use]
83	pub fn alias_is_local(&self, alias: &RoomAliasId) -> bool {
84		self.server_is_ours(alias.server_name())
85	}
86
87	#[inline]
88	#[must_use]
89	pub fn server_is_ours(&self, server_name: &ServerName) -> bool {
90		server_name == self.server_name()
91	}
92
93	#[inline]
94	#[must_use]
95	pub fn is_read_only(&self) -> bool { self.db.db.is_read_only() }
96
97	/// Reads `turn_secret_file` on every call, so a rotated secret takes effect
98	/// without a restart.
99	#[must_use]
100	pub fn turn_secret(&self) -> Option<Secret> {
101		let config = &self.server.config;
102
103		resolve_secret(
104			config.turn_secret_file.as_deref(),
105			config.turn_secret.as_deref(),
106			"TURN secret",
107		)
108	}
109
110	pub fn init_rustls_provider(&self) -> Result {
111		if rustls::crypto::CryptoProvider::get_default().is_none() {
112			rustls::crypto::aws_lc_rs::default_provider()
113				.install_default()
114				.map_err(|_provider| {
115					err!(error!("Error initialising aws_lc_rs rustls crypto backend"))
116				})
117		} else {
118			Ok(())
119		}
120	}
121}