2021-08-09 19:28:33 +00:00
|
|
|
use crate::mime::MimeMatcher;
|
2021-07-26 12:34:23 +00:00
|
|
|
use crate::random::RandomURLConfig;
|
2023-07-21 10:28:17 +00:00
|
|
|
use crate::AUTH_TOKEN_ENV;
|
2021-07-23 19:52:00 +00:00
|
|
|
use byte_unit::Byte;
|
|
|
|
use config::{self, ConfigError};
|
2023-07-21 10:28:17 +00:00
|
|
|
use std::env;
|
2021-11-07 13:06:57 +00:00
|
|
|
use std::path::{Path, PathBuf};
|
2022-03-11 21:02:25 +00:00
|
|
|
use std::time::Duration;
|
2021-07-23 19:52:00 +00:00
|
|
|
|
|
|
|
/// Configuration values.
|
2021-07-24 10:47:24 +00:00
|
|
|
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
|
2021-07-23 19:52:00 +00:00
|
|
|
pub struct Config {
|
2022-03-11 21:02:25 +00:00
|
|
|
/// Configuration settings.
|
2022-03-13 18:12:10 +00:00
|
|
|
#[serde(rename = "config")]
|
|
|
|
pub settings: Option<Settings>,
|
2021-07-23 19:52:00 +00:00
|
|
|
/// Server configuration.
|
|
|
|
pub server: ServerConfig,
|
|
|
|
/// Paste configuration.
|
|
|
|
pub paste: PasteConfig,
|
2023-06-23 15:20:24 +00:00
|
|
|
/// Landing page configuration.
|
|
|
|
pub landing_page: Option<LandingPageConfig>,
|
2021-07-23 19:52:00 +00:00
|
|
|
}
|
|
|
|
|
2022-03-11 21:02:25 +00:00
|
|
|
/// General settings for configuration.
|
|
|
|
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
|
|
|
|
pub struct Settings {
|
|
|
|
/// Refresh rate of the configuration file.
|
|
|
|
#[serde(with = "humantime_serde")]
|
|
|
|
pub refresh_rate: Duration,
|
|
|
|
}
|
|
|
|
|
2021-07-23 19:52:00 +00:00
|
|
|
/// Server configuration.
|
2021-07-24 10:47:24 +00:00
|
|
|
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
|
2021-07-23 19:52:00 +00:00
|
|
|
pub struct ServerConfig {
|
|
|
|
/// The socket address to bind.
|
|
|
|
pub address: String,
|
2023-05-13 20:20:52 +00:00
|
|
|
/// URL that can be used to access the server externally.
|
|
|
|
pub url: Option<String>,
|
2021-07-23 19:52:00 +00:00
|
|
|
/// Number of workers to start.
|
|
|
|
pub workers: Option<usize>,
|
|
|
|
/// Maximum content length.
|
|
|
|
pub max_content_length: Byte,
|
|
|
|
/// Storage path.
|
|
|
|
pub upload_path: PathBuf,
|
2022-03-11 21:35:54 +00:00
|
|
|
/// Request timeout.
|
|
|
|
#[serde(default, with = "humantime_serde")]
|
|
|
|
pub timeout: Option<Duration>,
|
2022-02-24 20:51:47 +00:00
|
|
|
/// Authentication token.
|
2023-07-21 10:28:17 +00:00
|
|
|
#[deprecated(note = "use [server].auth_tokens instead")]
|
2022-02-24 20:51:47 +00:00
|
|
|
pub auth_token: Option<String>,
|
2023-07-21 10:28:17 +00:00
|
|
|
/// Authentication tokens.
|
|
|
|
pub auth_tokens: Option<Vec<String>>,
|
2023-06-23 15:20:24 +00:00
|
|
|
/// Expose version.
|
|
|
|
pub expose_version: Option<bool>,
|
2022-10-03 21:27:35 +00:00
|
|
|
/// Landing page text.
|
2023-06-23 15:20:24 +00:00
|
|
|
#[deprecated(note = "use the [landing_page] table")]
|
2022-10-03 21:27:35 +00:00
|
|
|
pub landing_page: Option<String>,
|
2023-06-23 15:20:24 +00:00
|
|
|
/// Landing page content-type.
|
|
|
|
#[deprecated(note = "use the [landing_page] table")]
|
|
|
|
pub landing_page_content_type: Option<String>,
|
2023-08-07 10:55:13 +00:00
|
|
|
/// Path of the JSON index.
|
|
|
|
pub expose_list: Option<bool>,
|
2023-06-23 15:20:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Landing page configuration.
|
|
|
|
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
|
|
|
|
pub struct LandingPageConfig {
|
|
|
|
/// Landing page text.
|
|
|
|
pub text: Option<String>,
|
2023-06-16 14:21:44 +00:00
|
|
|
/// Landing page file.
|
2023-06-23 15:20:24 +00:00
|
|
|
pub file: Option<String>,
|
2023-05-27 22:16:46 +00:00
|
|
|
/// Landing page content-type
|
2023-06-23 15:20:24 +00:00
|
|
|
pub content_type: Option<String>,
|
2021-07-23 19:52:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Paste configuration.
|
2021-07-24 10:47:24 +00:00
|
|
|
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
|
2021-07-23 19:52:00 +00:00
|
|
|
pub struct PasteConfig {
|
2021-07-26 12:34:23 +00:00
|
|
|
/// Random URL configuration.
|
2023-08-20 18:32:41 +00:00
|
|
|
pub random_url: Option<RandomURLConfig>,
|
2021-07-23 19:52:00 +00:00
|
|
|
/// Default file extension.
|
|
|
|
pub default_extension: String,
|
2021-08-09 19:28:33 +00:00
|
|
|
/// Media type override options.
|
2022-05-21 03:25:23 +00:00
|
|
|
#[serde(default)]
|
2021-08-09 19:28:33 +00:00
|
|
|
pub mime_override: Vec<MimeMatcher>,
|
2021-08-09 19:48:51 +00:00
|
|
|
/// Media type blacklist.
|
2022-05-21 03:25:23 +00:00
|
|
|
#[serde(default)]
|
2021-08-09 19:48:51 +00:00
|
|
|
pub mime_blacklist: Vec<String>,
|
2023-05-13 22:30:35 +00:00
|
|
|
/// Allow duplicate uploads.
|
2021-10-12 16:35:06 +00:00
|
|
|
pub duplicate_files: Option<bool>,
|
2023-05-13 22:30:35 +00:00
|
|
|
/// Default expiry time.
|
|
|
|
#[serde(default, with = "humantime_serde")]
|
|
|
|
pub default_expiry: Option<Duration>,
|
2022-03-23 08:38:32 +00:00
|
|
|
/// Delete expired files.
|
|
|
|
pub delete_expired_files: Option<CleanupConfig>,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Cleanup configuration.
|
|
|
|
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
|
|
|
|
pub struct CleanupConfig {
|
|
|
|
/// Enable cleaning up.
|
|
|
|
pub enabled: bool,
|
|
|
|
/// Interval between clean-ups.
|
|
|
|
#[serde(default, with = "humantime_serde")]
|
|
|
|
pub interval: Duration,
|
2021-07-23 19:52:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Config {
|
|
|
|
/// Parses the config file and returns the values.
|
2021-11-07 13:06:57 +00:00
|
|
|
pub fn parse(path: &Path) -> Result<Config, ConfigError> {
|
2022-02-24 21:10:52 +00:00
|
|
|
config::Config::builder()
|
|
|
|
.add_source(config::File::from(path))
|
|
|
|
.add_source(config::Environment::default().separator("__"))
|
|
|
|
.build()?
|
|
|
|
.try_deserialize()
|
2021-07-23 19:52:00 +00:00
|
|
|
}
|
2023-07-21 10:28:17 +00:00
|
|
|
|
|
|
|
/// Retrieves all configured tokens.
|
|
|
|
#[allow(deprecated)]
|
|
|
|
pub fn get_tokens(&self) -> Option<Vec<String>> {
|
|
|
|
let mut tokens = self.server.auth_tokens.clone().unwrap_or_default();
|
|
|
|
if let Some(token) = &self.server.auth_token {
|
|
|
|
tokens.insert(0, token.to_string());
|
|
|
|
}
|
|
|
|
if let Ok(env_token) = env::var(AUTH_TOKEN_ENV) {
|
|
|
|
tokens.insert(0, env_token);
|
|
|
|
}
|
|
|
|
(!tokens.is_empty()).then_some(tokens)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Print deprecation warnings.
|
|
|
|
#[allow(deprecated)]
|
|
|
|
pub fn warn_deprecation(&self) {
|
|
|
|
if self.server.auth_token.is_some() {
|
|
|
|
log::warn!("[server].auth_token is deprecated, please use [server].auth_tokens");
|
|
|
|
}
|
|
|
|
if self.server.landing_page.is_some() {
|
|
|
|
log::warn!("[server].landing_page is deprecated, please use [landing_page].text");
|
|
|
|
}
|
|
|
|
if self.server.landing_page_content_type.is_some() {
|
|
|
|
log::warn!(
|
|
|
|
"[server].landing_page_content_type is deprecated, please use [landing_page].content_type"
|
|
|
|
);
|
|
|
|
}
|
2023-08-20 18:32:41 +00:00
|
|
|
if let Some(random_url) = &self.paste.random_url {
|
|
|
|
if random_url.enabled.is_some() {
|
|
|
|
log::warn!(
|
|
|
|
"[paste].random_url.enabled is deprecated, disable it by commenting out [paste].random_url"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2023-07-21 10:28:17 +00:00
|
|
|
}
|
2021-07-23 19:52:00 +00:00
|
|
|
}
|
2021-07-24 10:47:24 +00:00
|
|
|
|
|
|
|
#[cfg(test)]
|
2021-08-09 19:50:01 +00:00
|
|
|
mod tests {
|
2021-07-24 10:47:24 +00:00
|
|
|
use super::*;
|
|
|
|
use std::env;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_parse_config() -> Result<(), ConfigError> {
|
2021-11-07 13:06:57 +00:00
|
|
|
let config_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("config.toml");
|
2021-07-24 20:51:23 +00:00
|
|
|
env::set_var("SERVER__ADDRESS", "0.0.1.1");
|
2021-11-07 13:06:57 +00:00
|
|
|
let config = Config::parse(&config_path)?;
|
2021-07-24 10:47:24 +00:00
|
|
|
assert_eq!("0.0.1.1", config.server.address);
|
|
|
|
Ok(())
|
|
|
|
}
|
2023-08-20 18:32:41 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[allow(deprecated)]
|
|
|
|
fn test_parse_deprecated_config() -> Result<(), ConfigError> {
|
|
|
|
let config_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("config.toml");
|
|
|
|
env::set_var("SERVER__ADDRESS", "0.0.1.1");
|
|
|
|
let mut config = Config::parse(&config_path)?;
|
|
|
|
config.paste.random_url = Some(RandomURLConfig {
|
|
|
|
enabled: Some(true),
|
|
|
|
..RandomURLConfig::default()
|
|
|
|
});
|
|
|
|
assert_eq!("0.0.1.1", config.server.address);
|
|
|
|
config.warn_deprecation();
|
|
|
|
Ok(())
|
|
|
|
}
|
2021-07-24 10:47:24 +00:00
|
|
|
}
|