2023-01-25 01:26:22 +00:00
|
|
|
use std::path::PathBuf;
|
2021-04-09 00:22:17 +00:00
|
|
|
|
2023-04-24 15:35:32 +00:00
|
|
|
use log::Level as LogLevel;
|
2021-11-18 00:22:41 +00:00
|
|
|
use rsa::RsaPrivateKey;
|
2023-03-03 17:25:22 +00:00
|
|
|
use serde::Deserialize;
|
2021-11-10 14:32:27 +00:00
|
|
|
use url::Url;
|
2021-04-09 00:22:17 +00:00
|
|
|
|
2023-04-25 13:49:35 +00:00
|
|
|
use fedimovies_utils::urls::normalize_url;
|
2021-04-09 00:22:17 +00:00
|
|
|
|
2022-08-09 21:21:17 +00:00
|
|
|
use super::environment::Environment;
|
2023-02-22 22:14:42 +00:00
|
|
|
use super::federation::FederationConfig;
|
2023-01-30 00:23:16 +00:00
|
|
|
use super::limits::Limits;
|
2023-03-03 17:25:22 +00:00
|
|
|
use super::registration::RegistrationConfig;
|
2023-02-05 01:22:33 +00:00
|
|
|
use super::retention::RetentionConfig;
|
2023-04-08 23:34:07 +00:00
|
|
|
use super::REEF_VERSION;
|
2021-04-09 00:22:17 +00:00
|
|
|
|
2023-04-24 15:35:32 +00:00
|
|
|
fn default_log_level() -> LogLevel {
|
|
|
|
LogLevel::Info
|
|
|
|
}
|
2022-07-16 22:44:15 +00:00
|
|
|
|
2023-04-24 15:35:32 +00:00
|
|
|
fn default_login_message() -> String {
|
|
|
|
"What?!".to_string()
|
|
|
|
}
|
2022-07-16 22:44:15 +00:00
|
|
|
|
2021-04-09 00:22:17 +00:00
|
|
|
#[derive(Clone, Deserialize)]
|
|
|
|
pub struct Config {
|
2023-01-25 00:21:40 +00:00
|
|
|
// Properties auto-populated from the environment
|
2022-05-04 20:39:24 +00:00
|
|
|
#[serde(skip)]
|
2021-04-09 00:22:17 +00:00
|
|
|
pub environment: Environment,
|
|
|
|
|
2022-05-04 19:44:38 +00:00
|
|
|
#[serde(skip)]
|
|
|
|
pub config_path: String,
|
|
|
|
|
2021-04-09 00:22:17 +00:00
|
|
|
// Core settings
|
|
|
|
pub database_url: String,
|
2023-04-26 08:38:25 +00:00
|
|
|
#[serde(default)]
|
|
|
|
pub tls_ca_file: Option<PathBuf>,
|
2021-04-09 00:22:17 +00:00
|
|
|
pub storage_dir: PathBuf,
|
2022-12-22 20:27:56 +00:00
|
|
|
pub web_client_dir: Option<PathBuf>,
|
2021-04-09 00:22:17 +00:00
|
|
|
|
|
|
|
pub http_host: String,
|
|
|
|
pub http_port: u32,
|
|
|
|
|
2022-02-10 23:34:58 +00:00
|
|
|
#[serde(default)]
|
|
|
|
pub http_cors_allowlist: Vec<String>,
|
|
|
|
|
2021-12-21 00:14:12 +00:00
|
|
|
#[serde(default = "default_log_level")]
|
|
|
|
pub log_level: LogLevel,
|
|
|
|
|
2022-05-11 21:05:44 +00:00
|
|
|
// Domain name or <IP address>:<port>
|
2023-02-09 15:37:50 +00:00
|
|
|
// URI scheme is optional
|
2021-11-10 14:32:27 +00:00
|
|
|
instance_uri: String,
|
2023-02-09 15:37:50 +00:00
|
|
|
|
2021-04-09 00:22:17 +00:00
|
|
|
pub instance_title: String,
|
|
|
|
pub instance_short_description: String,
|
|
|
|
pub instance_description: String,
|
2022-04-30 19:26:09 +00:00
|
|
|
|
2023-04-25 11:19:04 +00:00
|
|
|
#[serde(default)]
|
|
|
|
pub tmdb_api_key: Option<String>,
|
|
|
|
#[serde(default)]
|
|
|
|
pub movie_user_password: Option<String>,
|
|
|
|
|
2022-04-30 19:26:09 +00:00
|
|
|
#[serde(skip)]
|
2023-01-25 01:26:22 +00:00
|
|
|
pub(super) instance_rsa_key: Option<RsaPrivateKey>,
|
2021-04-09 00:22:17 +00:00
|
|
|
|
2023-01-24 20:55:24 +00:00
|
|
|
pub(super) registrations_open: Option<bool>, // deprecated
|
|
|
|
|
2021-04-09 00:22:17 +00:00
|
|
|
#[serde(default)]
|
2023-01-24 20:55:24 +00:00
|
|
|
pub registration: RegistrationConfig,
|
2021-04-09 00:22:17 +00:00
|
|
|
|
2022-04-30 16:25:41 +00:00
|
|
|
// EIP-4361 login message
|
2022-05-11 21:10:48 +00:00
|
|
|
#[serde(default = "default_login_message")]
|
2021-04-09 00:22:17 +00:00
|
|
|
pub login_message: String,
|
|
|
|
|
2023-02-04 21:47:13 +00:00
|
|
|
pub(super) post_character_limit: Option<usize>, // deprecated
|
2022-02-08 21:04:28 +00:00
|
|
|
|
2023-01-30 00:23:16 +00:00
|
|
|
#[serde(default)]
|
|
|
|
pub limits: Limits,
|
|
|
|
|
2023-02-05 01:22:33 +00:00
|
|
|
#[serde(default)]
|
|
|
|
pub retention: RetentionConfig,
|
|
|
|
|
2023-02-22 22:14:42 +00:00
|
|
|
pub(super) proxy_url: Option<String>,
|
|
|
|
|
|
|
|
#[serde(default)]
|
2023-03-21 16:05:59 +00:00
|
|
|
pub federation: FederationConfig,
|
2023-02-22 22:14:42 +00:00
|
|
|
|
2022-02-23 23:31:56 +00:00
|
|
|
#[serde(default)]
|
|
|
|
pub blocked_instances: Vec<String>,
|
|
|
|
|
2022-01-25 22:17:28 +00:00
|
|
|
// IPFS
|
2021-04-09 00:22:17 +00:00
|
|
|
pub ipfs_api_url: Option<String>,
|
|
|
|
pub ipfs_gateway_url: Option<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Config {
|
2023-02-05 21:30:51 +00:00
|
|
|
pub(super) fn try_instance_url(&self) -> Result<Url, url::ParseError> {
|
2023-02-09 15:37:50 +00:00
|
|
|
normalize_url(&self.instance_uri)
|
2021-11-10 14:32:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn instance(&self) -> Instance {
|
2021-11-18 00:22:41 +00:00
|
|
|
Instance {
|
|
|
|
_url: self.try_instance_url().unwrap(),
|
2022-04-30 19:26:09 +00:00
|
|
|
actor_key: self.instance_rsa_key.clone().unwrap(),
|
2023-02-22 22:14:42 +00:00
|
|
|
proxy_url: self.federation.proxy_url.clone(),
|
2023-03-06 14:30:34 +00:00
|
|
|
onion_proxy_url: self.federation.onion_proxy_url.clone(),
|
2023-04-22 13:41:17 +00:00
|
|
|
i2p_proxy_url: self.federation.i2p_proxy_url.clone(),
|
2023-03-21 16:05:59 +00:00
|
|
|
// Private instance doesn't send activities and sign requests
|
2023-04-25 11:19:04 +00:00
|
|
|
is_private: !self.federation.enabled,
|
|
|
|
// || matches!(self.environment, Environment::Development),
|
2023-02-22 22:14:42 +00:00
|
|
|
fetcher_timeout: self.federation.fetcher_timeout,
|
|
|
|
deliverer_timeout: self.federation.deliverer_timeout,
|
2021-11-18 00:22:41 +00:00
|
|
|
}
|
2021-04-09 00:22:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn instance_url(&self) -> String {
|
2021-11-10 14:32:27 +00:00
|
|
|
self.instance().url()
|
2021-04-09 00:22:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn media_dir(&self) -> PathBuf {
|
|
|
|
self.storage_dir.join("media")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-13 21:38:01 +00:00
|
|
|
#[derive(Clone)]
|
2021-11-10 14:32:27 +00:00
|
|
|
pub struct Instance {
|
|
|
|
_url: Url,
|
2021-11-18 00:22:41 +00:00
|
|
|
// Instance actor
|
|
|
|
pub actor_key: RsaPrivateKey,
|
2022-10-19 18:39:47 +00:00
|
|
|
// Proxy for outgoing requests
|
|
|
|
pub proxy_url: Option<String>,
|
2023-03-06 14:30:34 +00:00
|
|
|
pub onion_proxy_url: Option<String>,
|
2023-04-22 13:41:17 +00:00
|
|
|
pub i2p_proxy_url: Option<String>,
|
2021-11-18 14:56:52 +00:00
|
|
|
// Private instance won't send signed HTTP requests
|
|
|
|
pub is_private: bool,
|
2023-02-22 22:14:42 +00:00
|
|
|
pub fetcher_timeout: u64,
|
|
|
|
pub deliverer_timeout: u64,
|
2021-11-10 14:32:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Instance {
|
|
|
|
pub fn url(&self) -> String {
|
|
|
|
self._url.origin().ascii_serialization()
|
|
|
|
}
|
|
|
|
|
2022-11-24 01:51:43 +00:00
|
|
|
pub fn hostname(&self) -> String {
|
2021-11-10 14:32:27 +00:00
|
|
|
self._url.host_str().unwrap().to_string()
|
|
|
|
}
|
2021-11-18 00:51:56 +00:00
|
|
|
|
2022-02-08 19:51:40 +00:00
|
|
|
pub fn agent(&self) -> String {
|
|
|
|
format!(
|
2023-04-08 23:34:07 +00:00
|
|
|
"Reef {version}; {instance_url}",
|
2023-04-24 15:35:32 +00:00
|
|
|
version = REEF_VERSION,
|
|
|
|
instance_url = self.url(),
|
2022-02-08 19:51:40 +00:00
|
|
|
)
|
|
|
|
}
|
2021-11-10 14:32:27 +00:00
|
|
|
}
|
|
|
|
|
2023-02-18 23:52:48 +00:00
|
|
|
#[cfg(feature = "test-utils")]
|
2023-01-12 21:38:36 +00:00
|
|
|
impl Instance {
|
|
|
|
pub fn for_test(url: &str) -> Self {
|
2023-04-25 13:49:35 +00:00
|
|
|
use fedimovies_utils::crypto_rsa::generate_weak_rsa_key;
|
2023-01-12 21:38:36 +00:00
|
|
|
Self {
|
|
|
|
_url: Url::parse(url).unwrap(),
|
|
|
|
actor_key: generate_weak_rsa_key().unwrap(),
|
|
|
|
proxy_url: None,
|
2023-03-06 14:30:34 +00:00
|
|
|
onion_proxy_url: None,
|
2023-04-22 13:41:17 +00:00
|
|
|
i2p_proxy_url: None,
|
2023-01-12 21:38:36 +00:00
|
|
|
is_private: true,
|
2023-02-22 22:14:42 +00:00
|
|
|
fetcher_timeout: 0,
|
|
|
|
deliverer_timeout: 0,
|
2023-01-12 21:38:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-10 14:32:27 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
2023-04-25 13:49:35 +00:00
|
|
|
use fedimovies_utils::crypto_rsa::generate_weak_rsa_key;
|
2021-11-10 14:32:27 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_instance_url_https_dns() {
|
|
|
|
let instance_url = Url::parse("https://example.com/").unwrap();
|
2022-11-13 18:43:57 +00:00
|
|
|
let instance_rsa_key = generate_weak_rsa_key().unwrap();
|
2021-11-18 00:22:41 +00:00
|
|
|
let instance = Instance {
|
|
|
|
_url: instance_url,
|
|
|
|
actor_key: instance_rsa_key,
|
2022-10-19 18:39:47 +00:00
|
|
|
proxy_url: None,
|
2023-03-06 14:30:34 +00:00
|
|
|
onion_proxy_url: None,
|
2023-04-22 13:41:17 +00:00
|
|
|
i2p_proxy_url: None,
|
2021-11-18 14:56:52 +00:00
|
|
|
is_private: true,
|
2023-02-22 22:14:42 +00:00
|
|
|
fetcher_timeout: 0,
|
|
|
|
deliverer_timeout: 0,
|
2021-11-18 00:22:41 +00:00
|
|
|
};
|
2021-11-10 14:32:27 +00:00
|
|
|
|
|
|
|
assert_eq!(instance.url(), "https://example.com");
|
2022-11-24 01:51:43 +00:00
|
|
|
assert_eq!(instance.hostname(), "example.com");
|
2023-01-25 01:05:21 +00:00
|
|
|
assert_eq!(
|
|
|
|
instance.agent(),
|
2023-04-08 23:34:07 +00:00
|
|
|
format!("Mitra {}; https://example.com", REEF_VERSION),
|
2023-01-25 01:05:21 +00:00
|
|
|
);
|
2021-11-10 14:32:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_instance_url_http_ipv4() {
|
|
|
|
let instance_url = Url::parse("http://1.2.3.4:3777/").unwrap();
|
2022-11-13 18:43:57 +00:00
|
|
|
let instance_rsa_key = generate_weak_rsa_key().unwrap();
|
2021-11-18 00:22:41 +00:00
|
|
|
let instance = Instance {
|
|
|
|
_url: instance_url,
|
|
|
|
actor_key: instance_rsa_key,
|
2022-10-19 18:39:47 +00:00
|
|
|
proxy_url: None,
|
2023-03-06 14:30:34 +00:00
|
|
|
onion_proxy_url: None,
|
2023-04-22 13:41:17 +00:00
|
|
|
i2p_proxy_url: None,
|
2021-11-18 14:56:52 +00:00
|
|
|
is_private: true,
|
2023-02-22 22:14:42 +00:00
|
|
|
fetcher_timeout: 0,
|
|
|
|
deliverer_timeout: 0,
|
2021-11-18 00:22:41 +00:00
|
|
|
};
|
2021-11-10 14:32:27 +00:00
|
|
|
|
|
|
|
assert_eq!(instance.url(), "http://1.2.3.4:3777");
|
2022-11-24 01:51:43 +00:00
|
|
|
assert_eq!(instance.hostname(), "1.2.3.4");
|
2021-11-10 14:32:27 +00:00
|
|
|
}
|
|
|
|
}
|