diff options
Diffstat (limited to 'crates')
6 files changed, 118 insertions, 49 deletions
diff --git a/crates/vcs_data/Cargo.toml b/crates/vcs_data/Cargo.toml index 3093809..d1f7e94 100644 --- a/crates/vcs_data/Cargo.toml +++ b/crates/vcs_data/Cargo.toml @@ -18,6 +18,7 @@ vcs_docs = { path = "../vcs_docs" } # Identity uuid = { version = "1.18.1", features = ["v4", "serde"] } +whoami = "1.6.1" # Serialization serde = { version = "1.0.228", features = ["derive"] } diff --git a/crates/vcs_data/src/data/vault.rs b/crates/vcs_data/src/data/vault.rs index 7cbb459..5c71d93 100644 --- a/crates/vcs_data/src/data/vault.rs +++ b/crates/vcs_data/src/data/vault.rs @@ -1,11 +1,7 @@ -use std::{ - env::current_dir, - fs::{self, create_dir_all}, - path::PathBuf, - sync::Arc, -}; +use std::{env::current_dir, path::PathBuf, sync::Arc}; use cfg_file::config::ConfigFile; +use tokio::fs::create_dir_all; use vcs_docs::docs::READMES_VAULT_README; use crate::{ @@ -53,7 +49,10 @@ impl Vault { } /// Setup vault - pub async fn setup_vault(vault_path: impl Into<PathBuf>) -> Result<(), std::io::Error> { + pub async fn setup_vault( + vault_path: impl Into<PathBuf>, + vault_name: impl AsRef<str>, + ) -> Result<(), std::io::Error> { let vault_path: PathBuf = vault_path.into(); // Ensure directory is empty @@ -66,19 +65,36 @@ impl Vault { // 1. Setup main config let config = VaultConfig::default(); - VaultConfig::write_to(&config, vault_path.join(SERVER_FILE_VAULT)).await?; + + // NOTE: + // Do not use the write_to method provided by the ConfigFile trait to store the Vault configuration file + // Instead, use the PROFILES_VAULT content provided by the Documents Repository for writing + + // VaultConfig::write_to(&config, vault_path.join(SERVER_FILE_VAULT)).await?; + let config_content = vcs_docs::docs::PROFILES_VAULT + .replace("{vault_name}", vault_name.as_ref()) + .replace("{user_name}", whoami::username().as_str()) + .replace( + "{date_format}", + chrono::Local::now() + .format("%Y-%m-%d %H:%M") + .to_string() + .as_str(), + ) + .replace("{vault_uuid}", &config.vault_uuid().to_string()); + tokio::fs::write(vault_path.join(SERVER_FILE_VAULT), config_content).await?; // 2. Setup sheets directory - create_dir_all(vault_path.join(SERVER_PATH_SHEETS))?; + create_dir_all(vault_path.join(SERVER_PATH_SHEETS)).await?; // 3. Setup key directory - create_dir_all(vault_path.join(SERVER_PATH_MEMBER_PUB))?; + create_dir_all(vault_path.join(SERVER_PATH_MEMBER_PUB)).await?; // 4. Setup member directory - create_dir_all(vault_path.join(SERVER_PATH_MEMBERS))?; + create_dir_all(vault_path.join(SERVER_PATH_MEMBERS)).await?; // 5. Setup storage directory - create_dir_all(vault_path.join(SERVER_PATH_VF_ROOT))?; + create_dir_all(vault_path.join(SERVER_PATH_VF_ROOT)).await?; let Some(vault) = Vault::init(config, &vault_path) else { return Err(std::io::Error::other("Failed to initialize vault")); @@ -96,14 +112,16 @@ impl Vault { // Final, generate README.md let readme_content = READMES_VAULT_README; - fs::write(vault_path.join(SERVER_FILE_README), readme_content)?; + tokio::fs::write(vault_path.join(SERVER_FILE_README), readme_content).await?; Ok(()) } /// Setup vault in current directory - pub async fn setup_vault_current_dir() -> Result<(), std::io::Error> { - Self::setup_vault(current_dir()?).await?; + pub async fn setup_vault_current_dir( + vault_name: impl AsRef<str>, + ) -> Result<(), std::io::Error> { + Self::setup_vault(current_dir()?, vault_name).await?; Ok(()) } diff --git a/crates/vcs_data/src/data/vault/config.rs b/crates/vcs_data/src/data/vault/config.rs index 1770a44..0855e89 100644 --- a/crates/vcs_data/src/data/vault/config.rs +++ b/crates/vcs_data/src/data/vault/config.rs @@ -10,43 +10,107 @@ use crate::data::member::{Member, MemberId}; pub type VaultName = String; pub type VaultUuid = Uuid; +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum AuthMode { + /// Use asymmetric keys: both client and server need to register keys, after which they can connect + Key, + + /// Use password: the password stays on the server, and the client needs to set the password locally for connection + Password, + + /// No authentication: generally used in a strongly secure environment, skipping verification directly + NoAuth, +} + +#[derive(Serialize, Deserialize, Clone, PartialEq)] +#[serde(rename_all = "lowercase")] +pub enum LoggerLevel { + Debug, + Trace, + Info, +} + +#[derive(Serialize, Deserialize, Clone, PartialEq)] +#[serde(rename_all = "lowercase")] +pub enum ServiceEnabled { + Enable, + Disable, +} + +#[derive(Serialize, Deserialize, Clone, PartialEq)] +#[serde(rename_all = "lowercase")] +pub enum BehaviourEnabled { + Yes, + No, +} + +impl Into<bool> for ServiceEnabled { + fn into(self) -> bool { + match self { + ServiceEnabled::Enable => true, + ServiceEnabled::Disable => false, + } + } +} + +impl Into<bool> for BehaviourEnabled { + fn into(self) -> bool { + match self { + BehaviourEnabled::Yes => true, + BehaviourEnabled::No => false, + } + } +} + #[derive(Serialize, Deserialize, ConfigFile)] #[cfg_file(path = SERVER_FILE_VAULT)] pub struct VaultConfig { /// Vault uuid, unique identifier for the vault + #[serde(rename = "uuid")] vault_uuid: VaultUuid, /// Vault name, which can be used as the project name and generally serves as a hint + #[serde(rename = "name")] vault_name: VaultName, /// Vault admin id, a list of member id representing administrator identities + #[serde(rename = "admin")] vault_admin_list: Vec<MemberId>, /// Vault server configuration, which will be loaded when connecting to the server + #[serde(rename = "profile")] server_config: VaultServerConfig, } #[derive(Serialize, Deserialize)] pub struct VaultServerConfig { /// Local IP address to bind to when the server starts + #[serde(rename = "bind")] local_bind: IpAddr, /// TCP port to bind to when the server starts + #[serde(rename = "port")] port: u16, /// Enable logging - logger: bool, + #[serde(rename = "logger")] + logger: BehaviourEnabled, + + /// Logger Level + #[serde(rename = "logger_level")] + logger_level: LoggerLevel, /// Whether to enable LAN discovery, allowing members on the same LAN to more easily find the upstream server - lan_discovery: bool, // TODO - - /// Authentication strength level - /// 0: Weakest - Anyone can claim any identity, fastest speed - /// 1: Basic - Any device can claim any registered identity, slightly faster - /// 2: Advanced - Uses asymmetric encryption, multiple devices can use key authentication to log in simultaneously, slightly slower - /// 3: Secure - Uses asymmetric encryption, only one device can use key for authentication at a time, much slower - /// Default is "Advanced", if using a lower security policy, ensure your server is only accessible by trusted devices - auth_strength: u8, // TODO + #[serde(rename = "lan_discovery")] + lan_discovery: ServiceEnabled, // TODO + + /// Authentication mode for the vault server + /// key: Use asymmetric keys for authentication + /// password: Use a password for authentication + /// noauth: No authentication required, requires a strongly secure environment + #[serde(rename = "auth_mode")] + auth_mode: AuthMode, // TODO } impl Default for VaultConfig { @@ -58,9 +122,10 @@ impl Default for VaultConfig { server_config: VaultServerConfig { local_bind: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), port: PORT, - logger: true, - lan_discovery: false, - auth_strength: 2, + logger: BehaviourEnabled::Yes, + logger_level: LoggerLevel::Info, + lan_discovery: ServiceEnabled::Disable, + auth_mode: AuthMode::Password, }, } } @@ -134,28 +199,13 @@ impl VaultServerConfig { &self.local_bind } - /// Set local bind IP address - pub fn set_local_bind(&mut self, local_bind: IpAddr) { - self.local_bind = local_bind; - } - /// Get port pub fn port(&self) -> u16 { self.port } - /// Set port - pub fn set_port(&mut self, port: u16) { - self.port = port; - } - /// Get logger enabled status pub fn is_logger_enabled(&self) -> bool { - self.logger - } - - /// Set logger enabled status - pub fn set_logger_enabled(&mut self, logger: bool) { - self.logger = logger; + self.logger.clone().into() } } diff --git a/crates/vcs_data/vcs_data_test/src/test_sheet_creation_management_and_persistence.rs b/crates/vcs_data/vcs_data_test/src/test_sheet_creation_management_and_persistence.rs index a89fbea..387e7e1 100644 --- a/crates/vcs_data/vcs_data_test/src/test_sheet_creation_management_and_persistence.rs +++ b/crates/vcs_data/vcs_data_test/src/test_sheet_creation_management_and_persistence.rs @@ -17,7 +17,7 @@ async fn test_sheet_creation_management_and_persistence() -> Result<(), std::io: let dir = get_test_dir("sheet_management").await?; // Setup vault - Vault::setup_vault(dir.clone()).await?; + Vault::setup_vault(dir.clone(), "TestVault").await?; // Get vault let config = VaultConfig::read_from(dir.join(SERVER_FILE_VAULT)).await?; @@ -193,7 +193,7 @@ async fn test_sheet_error_conditions() -> Result<(), std::io::Error> { let dir = get_test_dir("sheet_error_conditions").await?; // Setup vault - Vault::setup_vault(dir.clone()).await?; + Vault::setup_vault(dir.clone(), "TestVault").await?; // Get vault let config = VaultConfig::read_from(dir.join(SERVER_FILE_VAULT)).await?; @@ -244,7 +244,7 @@ async fn test_sheet_data_serialization() -> Result<(), std::io::Error> { // Test serialization by creating a sheet through the vault // Setup vault - Vault::setup_vault(dir.clone()).await?; + Vault::setup_vault(dir.clone(), "TestVault").await?; // Get vault let config = VaultConfig::read_from(dir.join(SERVER_FILE_VAULT)).await?; diff --git a/crates/vcs_data/vcs_data_test/src/test_vault_setup_and_member_register.rs b/crates/vcs_data/vcs_data_test/src/test_vault_setup_and_member_register.rs index 80ae39e..286a4a2 100644 --- a/crates/vcs_data/vcs_data_test/src/test_vault_setup_and_member_register.rs +++ b/crates/vcs_data/vcs_data_test/src/test_vault_setup_and_member_register.rs @@ -19,7 +19,7 @@ async fn test_vault_setup_and_member_register() -> Result<(), std::io::Error> { let dir = get_test_dir("member_register").await?; // Setup vault - Vault::setup_vault(dir.clone()).await?; + Vault::setup_vault(dir.clone(), "TestVault").await?; // Check if the following files and directories are created in `dir`: // Files: SERVER_FILE_VAULT, SERVER_FILE_README diff --git a/crates/vcs_data/vcs_data_test/src/test_virtual_file_creation_and_update.rs b/crates/vcs_data/vcs_data_test/src/test_virtual_file_creation_and_update.rs index 7e30dad..2d9d393 100644 --- a/crates/vcs_data/vcs_data_test/src/test_virtual_file_creation_and_update.rs +++ b/crates/vcs_data/vcs_data_test/src/test_virtual_file_creation_and_update.rs @@ -59,7 +59,7 @@ impl ServerHandle<VirtualFileCreateClientHandle> for VirtualFileCreateServerHand .unwrap(); // Setup vault - Vault::setup_vault(dir.clone()).await.unwrap(); + Vault::setup_vault(dir.clone(), "TestVault").await.unwrap(); // Read vault let Some(vault) = Vault::init( |
