Add SMB Configuration Templates (Phase 6)
This commit is contained in:
@@ -19,6 +19,7 @@ pub mod s3_config;
|
||||
pub mod s3_policy;
|
||||
pub mod s3_xml;
|
||||
pub mod scan;
|
||||
pub mod smb_config;
|
||||
pub mod server;
|
||||
pub mod ssh_server;
|
||||
pub mod sync;
|
||||
|
||||
339
markbase-core/src/smb_config.rs
Normal file
339
markbase-core/src/smb_config.rs
Normal file
@@ -0,0 +1,339 @@
|
||||
//! SMB Server Configuration Templates
|
||||
//! Provides preset configurations for common deployment scenarios
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// SMB Server Configuration
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SmbConfig {
|
||||
pub port: u16,
|
||||
pub root: PathBuf,
|
||||
pub share_name: String,
|
||||
pub read_only: bool,
|
||||
pub users: Vec<(String, String)>,
|
||||
pub backend: SmbBackend,
|
||||
pub ldap: Option<LdapConfig>,
|
||||
pub cache: CacheConfig,
|
||||
pub encryption: EncryptionConfig,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum SmbBackend {
|
||||
LocalFs,
|
||||
S3 {
|
||||
endpoint: String,
|
||||
bucket: String,
|
||||
access_key: String,
|
||||
secret_key: String,
|
||||
region: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct LdapConfig {
|
||||
pub url: String,
|
||||
pub base_dn: String,
|
||||
pub bind_dn: String,
|
||||
pub bind_password: String,
|
||||
pub user_search_base: String,
|
||||
pub group_search_base: String,
|
||||
pub user_id_attr: String,
|
||||
pub user_filter: String,
|
||||
pub group_filter: String,
|
||||
pub home_dir_attr: String,
|
||||
pub home_dir_prefix: String,
|
||||
pub user_groups_attr: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CacheConfig {
|
||||
pub read_cache_size_mb: usize,
|
||||
pub write_cache_size_mb: usize,
|
||||
pub cache_ttl_secs: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum EncryptionConfig {
|
||||
Disabled,
|
||||
Aes128Ctr,
|
||||
Aes256Gcm,
|
||||
}
|
||||
|
||||
impl Default for SmbConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
port: 4445,
|
||||
root: PathBuf::from("/data/smb"),
|
||||
share_name: "share".to_string(),
|
||||
read_only: false,
|
||||
users: vec![("demo".to_string(), "demo123".to_string())],
|
||||
backend: SmbBackend::LocalFs,
|
||||
ldap: None,
|
||||
cache: CacheConfig::default(),
|
||||
encryption: EncryptionConfig::Aes128Ctr,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for LdapConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
url: "ldap://localhost:389".to_string(),
|
||||
base_dn: "dc=example,dc=com".to_string(),
|
||||
bind_dn: "cn=admin,dc=example,dc=com".to_string(),
|
||||
bind_password: "".to_string(),
|
||||
user_search_base: "ou=users,dc=example,dc=com".to_string(),
|
||||
group_search_base: "ou=groups,dc=example,dc=com".to_string(),
|
||||
user_id_attr: "uid".to_string(),
|
||||
user_filter: "(objectClass=person)".to_string(),
|
||||
group_filter: "(objectClass=group)".to_string(),
|
||||
home_dir_attr: "homeDirectory".to_string(),
|
||||
home_dir_prefix: "/home".to_string(),
|
||||
user_groups_attr: "memberOf".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CacheConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
read_cache_size_mb: 64,
|
||||
write_cache_size_mb: 32,
|
||||
cache_ttl_secs: 300,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SmbConfig {
|
||||
/// Generate TOML configuration template
|
||||
pub fn generate_template() -> String {
|
||||
let config = Self::default();
|
||||
|
||||
format!(
|
||||
"# === SMB Server Configuration ===
|
||||
# MarkBase SMB2/3 File Server
|
||||
|
||||
[smb]
|
||||
# === Network Settings ===
|
||||
port = {} # SMB server port (default: 4445)
|
||||
share_name = \"{}\" # Share name visible to clients
|
||||
read_only = {} # Read-only mode (default: false)
|
||||
|
||||
# === Storage Backend ===
|
||||
# Options: localfs, s3
|
||||
backend = \"localfs\" # Default: local filesystem
|
||||
root = \"{}\" # Local filesystem root path
|
||||
|
||||
# === User Authentication ===
|
||||
# Format: [[smb.users]]
|
||||
# name = \"username\"
|
||||
# password = \"password\" (bcrypt hashed in production)
|
||||
|
||||
[[smb.users]]
|
||||
name = \"{}\"
|
||||
password = \"{}\" # ⚠️ Use bcrypt hash in production
|
||||
|
||||
# === LDAP Integration (Optional) ===
|
||||
# Uncomment to enable LDAP authentication
|
||||
# [smb.ldap]
|
||||
# url = \"ldap://localhost:389\" # LDAP server URL
|
||||
# base_dn = \"dc=example,dc=com\" # Base DN
|
||||
# bind_dn = \"cn=admin,dc=example,dc=com\" # Bind DN for search
|
||||
# bind_password = \"admin_password\" # Bind password
|
||||
# user_search_base = \"ou=users,dc=example,dc=com\"
|
||||
# group_search_base = \"ou=groups,dc=example,dc=com\"
|
||||
# user_id_attr = \"uid\" # User ID attribute
|
||||
# user_filter = \"(objectClass=person)\" # User object filter
|
||||
# group_filter = \"(objectClass=group)\" # Group object filter
|
||||
# home_dir_attr = \"homeDirectory\" # Home directory attribute
|
||||
# home_dir_prefix = \"/home\" # Home directory prefix
|
||||
# user_groups_attr = \"memberOf\" # Group membership attribute
|
||||
|
||||
# === Performance Settings ===
|
||||
[smb.cache]
|
||||
read_cache_size_mb = {} # Read cache size (default: 64MB)
|
||||
write_cache_size_mb = {} # Write cache size (default: 32MB)
|
||||
cache_ttl_secs = {} # Cache TTL (default: 300s)
|
||||
|
||||
# === Security Settings ===
|
||||
[smb.encryption]
|
||||
# Options: disabled, aes128-ctr, aes256-gcm
|
||||
mode = \"aes128-ctr\" # SMB3 encryption mode (default: AES-128-CTR)
|
||||
|
||||
# === S3 Backend (Optional) ===
|
||||
# Uncomment to use S3 backend instead of local filesystem
|
||||
# [smb.s3]
|
||||
# endpoint = \"https://s3.amazonaws.com\"
|
||||
# bucket = \"my-bucket\"
|
||||
# access_key = \"AKIAIOSFODNN7EXAMPLE\"
|
||||
# secret_key = \"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\"
|
||||
# region = \"us-east-1\"
|
||||
",
|
||||
config.port,
|
||||
config.share_name,
|
||||
config.read_only,
|
||||
config.root.display(),
|
||||
config.users[0].0,
|
||||
config.users[0].1,
|
||||
config.cache.read_cache_size_mb,
|
||||
config.cache.write_cache_size_mb,
|
||||
config.cache.cache_ttl_secs,
|
||||
)
|
||||
}
|
||||
|
||||
/// Preset: Local File Server (simple deployment)
|
||||
pub fn preset_local_file_server() -> Self {
|
||||
Self {
|
||||
port: 4445,
|
||||
root: PathBuf::from("/data/smb"),
|
||||
share_name: "files".to_string(),
|
||||
read_only: false,
|
||||
users: vec![
|
||||
("alice".to_string(), "alice123".to_string()),
|
||||
("bob".to_string(), "bob123".to_string()),
|
||||
],
|
||||
backend: SmbBackend::LocalFs,
|
||||
ldap: None,
|
||||
cache: CacheConfig {
|
||||
read_cache_size_mb: 64,
|
||||
write_cache_size_mb: 32,
|
||||
cache_ttl_secs: 300,
|
||||
},
|
||||
encryption: EncryptionConfig::Aes128Ctr,
|
||||
}
|
||||
}
|
||||
|
||||
/// Preset: S3 Backend (cloud storage)
|
||||
pub fn preset_s3_backend() -> Self {
|
||||
Self {
|
||||
port: 4445,
|
||||
root: PathBuf::from("demo/"),
|
||||
share_name: "s3share".to_string(),
|
||||
read_only: false,
|
||||
users: vec![("demo".to_string(), "demo123".to_string())],
|
||||
backend: SmbBackend::S3 {
|
||||
endpoint: "https://s3.amazonaws.com".to_string(),
|
||||
bucket: "my-bucket".to_string(),
|
||||
access_key: "AKIAIOSFODNN7EXAMPLE".to_string(),
|
||||
secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY".to_string(),
|
||||
region: "us-east-1".to_string(),
|
||||
},
|
||||
ldap: None,
|
||||
cache: CacheConfig {
|
||||
read_cache_size_mb: 128,
|
||||
write_cache_size_mb: 64,
|
||||
cache_ttl_secs: 600,
|
||||
},
|
||||
encryption: EncryptionConfig::Aes256Gcm,
|
||||
}
|
||||
}
|
||||
|
||||
/// Preset: LDAP Enterprise (Active Directory integration)
|
||||
pub fn preset_ldap_enterprise() -> Self {
|
||||
Self {
|
||||
port: 4445,
|
||||
root: PathBuf::from("/data/smb"),
|
||||
share_name: "enterprise".to_string(),
|
||||
read_only: false,
|
||||
users: vec![], // LDAP handles authentication
|
||||
backend: SmbBackend::LocalFs,
|
||||
ldap: Some(LdapConfig {
|
||||
url: "ldap://ad.example.com:389".to_string(),
|
||||
base_dn: "dc=example,dc=com".to_string(),
|
||||
bind_dn: "cn=admin,cn=users,dc=example,dc=com".to_string(),
|
||||
bind_password: "admin_password".to_string(),
|
||||
user_search_base: "cn=users,dc=example,dc=com".to_string(),
|
||||
group_search_base: "cn=groups,dc=example,dc=com".to_string(),
|
||||
user_id_attr: "sAMAccountName".to_string(),
|
||||
user_filter: "(objectClass=user)".to_string(),
|
||||
group_filter: "(objectClass=group)".to_string(),
|
||||
home_dir_attr: "homeDirectory".to_string(),
|
||||
home_dir_prefix: "/home".to_string(),
|
||||
user_groups_attr: "memberOf".to_string(),
|
||||
}),
|
||||
cache: CacheConfig {
|
||||
read_cache_size_mb: 128,
|
||||
write_cache_size_mb: 64,
|
||||
cache_ttl_secs: 300,
|
||||
},
|
||||
encryption: EncryptionConfig::Aes256Gcm,
|
||||
}
|
||||
}
|
||||
|
||||
/// Preset: Read-Only Archive (public documents)
|
||||
pub fn preset_read_only_archive() -> Self {
|
||||
Self {
|
||||
port: 4445,
|
||||
root: PathBuf::from("/data/archive"),
|
||||
share_name: "archive".to_string(),
|
||||
read_only: true,
|
||||
users: vec![("public".to_string(), "".to_string())],
|
||||
backend: SmbBackend::LocalFs,
|
||||
ldap: None,
|
||||
cache: CacheConfig {
|
||||
read_cache_size_mb: 256,
|
||||
write_cache_size_mb: 0,
|
||||
cache_ttl_secs: 3600,
|
||||
},
|
||||
encryption: EncryptionConfig::Disabled,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_default_config() {
|
||||
let config = SmbConfig::default();
|
||||
assert_eq!(config.port, 4445);
|
||||
assert_eq!(config.share_name, "share");
|
||||
assert!(!config.read_only);
|
||||
assert_eq!(config.users.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_generate_template() {
|
||||
let template = SmbConfig::generate_template();
|
||||
assert!(template.contains("port = 4445"));
|
||||
assert!(template.contains("share_name = \"share\""));
|
||||
assert!(template.contains("backend = \"localfs\""));
|
||||
assert!(template.contains("[smb.users]"));
|
||||
assert!(template.contains("[smb.cache]"));
|
||||
assert!(template.contains("[smb.encryption]"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_preset_local_file_server() {
|
||||
let config = SmbConfig::preset_local_file_server();
|
||||
assert_eq!(config.port, 4445);
|
||||
assert_eq!(config.share_name, "files");
|
||||
assert_eq!(config.users.len(), 2);
|
||||
assert!(config.ldap.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_preset_s3_backend() {
|
||||
let config = SmbConfig::preset_s3_backend();
|
||||
assert_eq!(config.share_name, "s3share");
|
||||
assert!(matches!(config.backend, SmbBackend::S3 { .. }));
|
||||
assert!(matches!(config.encryption, EncryptionConfig::Aes256Gcm));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_preset_ldap_enterprise() {
|
||||
let config = SmbConfig::preset_ldap_enterprise();
|
||||
assert_eq!(config.share_name, "enterprise");
|
||||
assert!(config.ldap.is_some());
|
||||
assert_eq!(config.users.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_preset_read_only_archive() {
|
||||
let config = SmbConfig::preset_read_only_archive();
|
||||
assert!(config.read_only);
|
||||
assert_eq!(config.share_name, "archive");
|
||||
assert!(matches!(config.encryption, EncryptionConfig::Disabled));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user