v0.1.2
RustBox CI / rustbox (push) Canceled after 0s

This commit is contained in:
Mateusz Gruszczyński committed 2026-10-31 09:22:42 +01:00
1 parent 698e3c4a1b
commit e3e844ef4f
31 files changed
+287 -75

No files matched your search

+59
View File
@@ -46,6 +46,9 @@ pub struct AppConfig {
#[serde(default)]
pub log_dir: Option<String>,
#[serde(default = "default_log_level")]
pub log_level: String,
#[serde(default = "default_database_backend")]
pub database_backend: String,
@@ -76,6 +79,12 @@ pub struct AppConfig {
#[serde(default)]
pub cluster_mode: bool,
#[serde(default)]
pub cluster_shared_data_dir: bool,
#[serde(default = "default_search_index_backend")]
pub search_index_backend: String,
#[serde(default = "default_session_timeout_hours")]
pub session_timeout_hours: u64,
@@ -118,6 +127,9 @@ pub struct AppConfig {
#[serde(default)]
pub outgoing_headers: Vec<String>,
#[serde(default = "default_pgp_enabled")]
pub pgp_enabled: bool,
#[serde(default = "default_pgp_wkd_enabled")]
pub pgp_wkd_enabled: bool,
@@ -199,6 +211,10 @@ fn default_data_dir() -> String {
"/data".to_string()
}
fn default_log_level() -> String {
"info".to_string()
}
fn default_database_backend() -> String {
"sqlite".to_string()
}
@@ -207,6 +223,10 @@ fn default_session_backend() -> String {
"database".to_string()
}
fn default_search_index_backend() -> String {
"tantivy".to_string()
}
fn default_session_timeout_hours() -> u64 {
24
}
@@ -242,6 +262,10 @@ fn default_sieve_timeout_secs() -> u64 {
10
}
fn default_pgp_enabled() -> bool {
true
}
fn default_pgp_wkd_enabled() -> bool {
true
}
@@ -270,6 +294,7 @@ impl Default for AppConfig {
max_message_size_mb: default_max_message_size_mb(),
data_dir: default_data_dir(),
log_dir: None,
log_level: default_log_level(),
database_backend: default_database_backend(),
database_url: None,
session_backend: default_session_backend(),
@@ -280,6 +305,8 @@ impl Default for AppConfig {
redis_password: None,
redis_sentinel_password: None,
cluster_mode: false,
cluster_shared_data_dir: false,
search_index_backend: default_search_index_backend(),
session_timeout_hours: default_session_timeout_hours(),
remember_me_enabled: default_remember_me_enabled(),
remember_me_days: default_remember_me_days(),
@@ -294,6 +321,7 @@ impl Default for AppConfig {
sieve_timeout_secs: default_sieve_timeout_secs(),
trusted_proxies: None,
outgoing_headers: Vec::new(),
pgp_enabled: default_pgp_enabled(),
pgp_wkd_enabled: default_pgp_wkd_enabled(),
pgp_hkp_enabled: false,
pgp_hkp_url: default_pgp_hkp_url(),
@@ -446,6 +474,16 @@ impl AppConfig {
return Err("LOG_DIR / log_dir must be an absolute path".to_string());
}
}
let log_level = self.log_level.trim().to_ascii_lowercase();
if !matches!(
log_level.as_str(),
"trace" | "debug" | "info" | "warn" | "error" | "off"
) {
return Err(
"LOG_LEVEL / log_level must be one of: trace, debug, info, warn, error, off"
.to_string(),
);
}
if self.max_attachment_size_mb == 0 || self.max_attachment_size_mb > 512 {
return Err("MAX_ATTACHMENT_SIZE_MB must be between 1 and 512".to_string());
}
@@ -492,12 +530,33 @@ impl AppConfig {
return Err("Redis sessions require REDIS_URL or REDIS_SENTINEL_NODES + REDIS_SENTINEL_MASTER".to_string());
}
}
if !matches!(self.search_index_backend.as_str(), "tantivy" | "disabled") {
return Err("SEARCH_INDEX_BACKEND must be one of: tantivy, disabled".to_string());
}
if self.cluster_mode && self.database_backend == "sqlite" {
return Err(
"CLUSTER_MODE requires a shared mysql/pgsql application database; Redis only replaces session persistence"
.to_string(),
);
}
if self.cluster_mode && !self.cluster_shared_data_dir {
return Err(
"CLUSTER_MODE requires CLUSTER_SHARED_DATA_DIR=true after data_dir is mounted as shared storage on every node; draft attachments are stored below data_dir"
.to_string(),
);
}
if self.cluster_mode && self.search_index_backend != "disabled" {
return Err(
"CLUSTER_MODE requires SEARCH_INDEX_BACKEND=disabled; the built-in Tantivy index is local and does not coordinate writers across nodes"
.to_string(),
);
}
if self.cluster_mode && self.pgp_enabled {
return Err(
"CLUSTER_MODE requires PGP_ENABLED=false; OpenPGP private keys use node-local filesystem storage"
.to_string(),
);
}
if (self.cluster_mode
|| self.session_backend == "redis"
|| self.database_backend != "sqlite")