Add server config for mergable extensions

This commit is contained in:
Andras Schmelczer 2025-11-23 21:55:33 +00:00
parent 7008c54e2e
commit c3cbde052a
16 changed files with 214 additions and 71 deletions

View file

@ -8,6 +8,9 @@ server:
max_body_size_mb: 512
max_clients_per_vault: 256
response_timeout_seconds: 60
mergeable_file_extensions:
- md
- txt
users:
user_configs:
- name: admin

View file

@ -2,8 +2,8 @@ use log::debug;
use serde::{Deserialize, Serialize};
use crate::consts::{
DEFAULT_HOST, DEFAULT_MAX_BODY_SIZE_MB, DEFAULT_MAX_CLIENTS_PER_VAULT, DEFAULT_PORT,
DEFAULT_RESPONSE_TIMEOUT_SECONDS,
DEFAULT_HOST, DEFAULT_MAX_BODY_SIZE_MB, DEFAULT_MAX_CLIENTS_PER_VAULT,
DEFAULT_MERGEABLE_FILE_EXTENSIONS, DEFAULT_PORT, DEFAULT_RESPONSE_TIMEOUT_SECONDS,
};
#[derive(Debug, Deserialize, Serialize, Clone, Default)]
@ -22,6 +22,9 @@ pub struct ServerConfig {
#[serde(default = "default_response_timeout_seconds")]
pub response_timeout_seconds: u64,
#[serde(default = "default_mergeable_file_extensions")]
pub mergeable_file_extensions: Vec<String>,
}
fn default_host() -> String {
@ -48,3 +51,11 @@ fn default_response_timeout_seconds() -> u64 {
debug!("Using default response timeout (seconds): {DEFAULT_RESPONSE_TIMEOUT_SECONDS}");
DEFAULT_RESPONSE_TIMEOUT_SECONDS
}
fn default_mergeable_file_extensions() -> Vec<String> {
debug!("Using default mergeable file extensions: {DEFAULT_MERGEABLE_FILE_EXTENSIONS:?}");
DEFAULT_MERGEABLE_FILE_EXTENSIONS
.iter()
.map(|s| (*s).to_owned())
.collect()
}

View file

@ -14,3 +14,5 @@ pub const DEFAULT_MAX_CLIENTS_PER_VAULT: usize = 256;
pub const DEFAULT_LOG_DIRECTORY: &str = "logs";
pub const DEFAULT_LOG_ROTATION_INTERVAL: Duration = Duration::from_secs(60 * 60 * 24); // 1 day
pub const DEFAULT_MERGEABLE_FILE_EXTENSIONS: &[&str] = &["md", "txt"];

View file

@ -33,5 +33,6 @@ pub async fn ping(
Ok(Json(PingResponse {
server_version: env!("CARGO_PKG_VERSION").to_owned(),
is_authenticated,
mergeable_file_extensions: state.config.server.mergeable_file_extensions.clone(),
}))
}

View file

@ -16,6 +16,9 @@ pub struct PingResponse {
/// Whether the client is authenticated based on the sent Authorization
/// header.
pub is_authenticated: bool,
/// List of file extensions that are allowed to be merged.
pub mergeable_file_extensions: Vec<String>,
}
/// Response to a fetch latest documents request.

View file

@ -185,8 +185,10 @@ async fn update_document(
)));
}
let are_all_participants_mergable = is_file_type_mergable(&sanitized_relative_path)
&& !is_binary(&parent_document.content)
let are_all_participants_mergable = is_file_type_mergable(
&sanitized_relative_path,
&state.config.server.mergeable_file_extensions,
) && !is_binary(&parent_document.content)
&& !is_binary(&latest_version.content)
&& !is_binary(&content);

View file

@ -1,7 +1,10 @@
pub fn is_file_type_mergable(path_or_file_name: &str) -> bool {
pub fn is_file_type_mergable(path_or_file_name: &str, mergeable_extensions: &[String]) -> bool {
let file_extension = path_or_file_name.split('.').next_back().unwrap_or_default();
let file_extension_lower = file_extension.to_lowercase();
matches!(file_extension.to_lowercase().as_str(), "md" | "txt")
mergeable_extensions
.iter()
.any(|ext| ext.to_lowercase() == file_extension_lower)
}
#[cfg(test)]
@ -10,14 +13,22 @@ mod tests {
#[test]
fn test_is_file_type_mergable() {
assert!(is_file_type_mergable(".md"));
assert!(is_file_type_mergable("hi.md"));
assert!(is_file_type_mergable("my/path/to/my/document.md"));
assert!(is_file_type_mergable("hi.MD"));
assert!(is_file_type_mergable("my/path/to/my/DOCUMENT.MD"));
let mergeable = vec!["md".to_owned(), "txt".to_owned()];
assert!(!is_file_type_mergable(".json"));
assert!(!is_file_type_mergable("HELLO.JSON"));
assert!(!is_file_type_mergable("my/config.yml"));
assert!(is_file_type_mergable(".md", &mergeable));
assert!(is_file_type_mergable("hi.md", &mergeable));
assert!(is_file_type_mergable(
"my/path/to/my/document.md",
&mergeable
));
assert!(is_file_type_mergable("hi.MD", &mergeable));
assert!(is_file_type_mergable(
"my/path/to/my/DOCUMENT.MD",
&mergeable
));
assert!(!is_file_type_mergable(".json", &mergeable));
assert!(!is_file_type_mergable("HELLO.JSON", &mergeable));
assert!(!is_file_type_mergable("my/config.yml", &mergeable));
}
}