Skip to main content

cloudillo_core/
app.rs

1// SPDX-FileCopyrightText: Szilárd Hajba
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
4//! App state type
5
6use rustls::sign::CertifiedKey;
7use std::{
8	collections::HashMap,
9	path::Path,
10	sync::{Arc, RwLock},
11};
12
13use crate::extensions::Extensions;
14use crate::prelude::*;
15use crate::proxy_token_cache::ProxyTokenCache;
16use crate::{abac, request, scheduler, ws_broadcast::BroadcastManager};
17
18use cloudillo_types::auth_adapter::AuthAdapter;
19use cloudillo_types::blob_adapter::BlobAdapter;
20use cloudillo_types::crdt_adapter::CrdtAdapter;
21use cloudillo_types::identity_provider_adapter::IdentityProviderAdapter;
22use cloudillo_types::meta_adapter::MetaAdapter;
23use cloudillo_types::rtdb_adapter::RtdbAdapter;
24use cloudillo_types::worker;
25
26use crate::rate_limit::RateLimitManager;
27use crate::settings::service::SettingsService;
28use crate::settings::types::FrozenSettingsRegistry;
29
30pub const VERSION: &str = env!("CARGO_PKG_VERSION");
31
32#[derive(Debug, Clone, Copy)]
33pub enum ServerMode {
34	Standalone,
35	Proxy,
36	StreamProxy,
37}
38
39pub struct AppState {
40	pub scheduler: Arc<scheduler::Scheduler<App>>,
41	pub worker: Arc<worker::WorkerPool>,
42	pub request: request::Request,
43	pub proxy_tokens: Arc<ProxyTokenCache>,
44	pub acme_challenge_map: RwLock<HashMap<Box<str>, Box<str>>>,
45	pub certs: RwLock<HashMap<Box<str>, Arc<CertifiedKey>>>,
46	pub opts: AppBuilderOpts,
47	pub broadcast: BroadcastManager,
48	pub permission_checker: Arc<tokio::sync::RwLock<abac::PermissionChecker>>,
49
50	pub auth_adapter: Arc<dyn AuthAdapter>,
51	pub meta_adapter: Arc<dyn MetaAdapter>,
52	pub blob_adapter: Arc<dyn BlobAdapter>,
53	pub crdt_adapter: Arc<dyn CrdtAdapter>,
54	pub rtdb_adapter: Arc<dyn RtdbAdapter>,
55	pub idp_adapter: Option<Arc<dyn IdentityProviderAdapter>>,
56
57	// Settings subsystem
58	pub settings: Arc<SettingsService>,
59	pub settings_registry: Arc<FrozenSettingsRegistry>,
60
61	// Rate limiter
62	pub rate_limiter: Arc<RateLimitManager>,
63
64	// Type-erased extension map for feature-specific state
65	pub extensions: Extensions,
66}
67
68impl AppState {
69	/// Get a registered extension by type. Returns error if not found.
70	pub fn ext<T: Send + Sync + 'static>(&self) -> ClResult<&T> {
71		self.extensions.get::<T>().ok_or_else(|| {
72			Error::Internal(format!("Extension {} not registered", std::any::type_name::<T>()))
73		})
74	}
75}
76
77pub type App = Arc<AppState>;
78
79pub struct Adapters {
80	pub auth_adapter: Option<Arc<dyn AuthAdapter>>,
81	pub meta_adapter: Option<Arc<dyn MetaAdapter>>,
82	pub blob_adapter: Option<Arc<dyn BlobAdapter>>,
83	pub crdt_adapter: Option<Arc<dyn CrdtAdapter>>,
84	pub rtdb_adapter: Option<Arc<dyn RtdbAdapter>>,
85	pub idp_adapter: Option<Arc<dyn IdentityProviderAdapter>>,
86}
87
88#[derive(Debug)]
89pub struct AppBuilderOpts {
90	pub mode: ServerMode,
91	pub listen: Box<str>,
92	pub listen_http: Option<Box<str>>,
93	pub base_id_tag: Option<Box<str>>,
94	pub base_app_domain: Option<Box<str>>,
95	pub base_password: Option<Box<str>>,
96	pub dist_dir: Box<Path>,
97	pub tmp_dir: Box<Path>,
98	pub acme_email: Option<Box<str>>,
99	pub local_address: Box<[Box<str>]>,
100	/// Disable HTTP caching (for development)
101	pub disable_cache: bool,
102}
103
104// vim: ts=4