refactor: Improve Rhai test runner and vault module code
Some checks are pending
Rhai Tests / Run Rhai Tests (push) Waiting to run
Some checks are pending
Rhai Tests / Run Rhai Tests (push) Waiting to run
- Updated the Rhai test runner script to correctly find test files. - Improved the structure and formatting of the `vault.rs` module. - Minor code style improvements in multiple files.
This commit is contained in:
parent
a8ed0900fd
commit
3a0900fc15
@ -24,7 +24,7 @@ log "${BLUE} Running All Rhai Tests ${NC}"
|
|||||||
log "${BLUE}=======================================${NC}"
|
log "${BLUE}=======================================${NC}"
|
||||||
|
|
||||||
# Find all test runner scripts
|
# Find all test runner scripts
|
||||||
RUNNERS=$(find src/rhai_tests -name "run_all_tests.rhai")
|
RUNNERS=$(find rhai_tests -name "run_all_tests.rhai")
|
||||||
|
|
||||||
# Initialize counters
|
# Initialize counters
|
||||||
TOTAL_MODULES=0
|
TOTAL_MODULES=0
|
||||||
|
@ -1,29 +1,28 @@
|
|||||||
//! Rhai bindings for SAL crypto functionality
|
//! Rhai bindings for SAL crypto functionality
|
||||||
|
|
||||||
use rhai::{Engine, Dynamic, EvalAltResult};
|
use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _};
|
||||||
use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64};
|
use ethers::types::{Address, U256};
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use rhai::{Dynamic, Engine, EvalAltResult};
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::sync::Mutex;
|
|
||||||
use once_cell::sync::Lazy;
|
|
||||||
use tokio::runtime::Runtime;
|
|
||||||
use ethers::types::{Address, U256};
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
use tokio::runtime::Runtime;
|
||||||
|
|
||||||
use crate::vault::{keypair, ethereum};
|
use crate::vault::ethereum::contract_utils::{convert_token_to_rhai, prepare_function_arguments};
|
||||||
use crate::vault::ethereum::contract_utils::{prepare_function_arguments, convert_token_to_rhai};
|
use crate::vault::{ethereum, keypair};
|
||||||
|
|
||||||
use symmetric_impl::implementation as symmetric_impl;
|
use crate::vault::symmetric::implementation as symmetric_impl;
|
||||||
// Global Tokio runtime for blocking async operations
|
// Global Tokio runtime for blocking async operations
|
||||||
static RUNTIME: Lazy<Mutex<Runtime>> = Lazy::new(|| {
|
static RUNTIME: Lazy<Mutex<Runtime>> =
|
||||||
Mutex::new(Runtime::new().expect("Failed to create Tokio runtime"))
|
Lazy::new(|| Mutex::new(Runtime::new().expect("Failed to create Tokio runtime")));
|
||||||
});
|
|
||||||
|
|
||||||
// Global provider registry
|
// Global provider registry
|
||||||
static PROVIDERS: Lazy<Mutex<HashMap<String, ethers::providers::Provider<ethers::providers::Http>>>> = Lazy::new(|| {
|
static PROVIDERS: Lazy<
|
||||||
Mutex::new(HashMap::new())
|
Mutex<HashMap<String, ethers::providers::Provider<ethers::providers::Http>>>,
|
||||||
});
|
> = Lazy::new(|| Mutex::new(HashMap::new()));
|
||||||
|
|
||||||
// Key space management functions
|
// Key space management functions
|
||||||
fn load_key_space(name: &str, password: &str) -> bool {
|
fn load_key_space(name: &str, password: &str) -> bool {
|
||||||
@ -90,7 +89,8 @@ fn create_key_space(name: &str, password: &str) -> bool {
|
|||||||
match keypair::get_current_space() {
|
match keypair::get_current_space() {
|
||||||
Ok(space) => {
|
Ok(space) => {
|
||||||
// Encrypt the key space
|
// Encrypt the key space
|
||||||
let encrypted_space = match symmetric_impl::encrypt_key_space(&space, password) {
|
let encrypted_space = match symmetric_impl::encrypt_key_space(&space, password)
|
||||||
|
{
|
||||||
Ok(encrypted) => encrypted,
|
Ok(encrypted) => encrypted,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error encrypting key space: {}", e);
|
log::error!("Error encrypting key space: {}", e);
|
||||||
@ -99,7 +99,8 @@ fn create_key_space(name: &str, password: &str) -> bool {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Serialize the encrypted space
|
// Serialize the encrypted space
|
||||||
let serialized = match symmetric_impl::serialize_encrypted_space(&encrypted_space) {
|
let serialized =
|
||||||
|
match symmetric_impl::serialize_encrypted_space(&encrypted_space) {
|
||||||
Ok(json) => json,
|
Ok(json) => json,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error serializing encrypted space: {}", e);
|
log::error!("Error serializing encrypted space: {}", e);
|
||||||
@ -114,7 +115,7 @@ fn create_key_space(name: &str, password: &str) -> bool {
|
|||||||
// Create directory if it doesn't exist
|
// Create directory if it doesn't exist
|
||||||
if !key_spaces_dir.exists() {
|
if !key_spaces_dir.exists() {
|
||||||
match fs::create_dir_all(&key_spaces_dir) {
|
match fs::create_dir_all(&key_spaces_dir) {
|
||||||
Ok(_) => {},
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error creating key spaces directory: {}", e);
|
log::error!("Error creating key spaces directory: {}", e);
|
||||||
return false;
|
return false;
|
||||||
@ -128,19 +129,19 @@ fn create_key_space(name: &str, password: &str) -> bool {
|
|||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
log::info!("Key space created and saved to {}", space_path.display());
|
log::info!("Key space created and saved to {}", space_path.display());
|
||||||
true
|
true
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error writing key space file: {}", e);
|
log::error!("Error writing key space file: {}", e);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error getting current space: {}", e);
|
log::error!("Error getting current space: {}", e);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error creating key space: {}", e);
|
log::error!("Error creating key space: {}", e);
|
||||||
false
|
false
|
||||||
@ -177,7 +178,7 @@ fn auto_save_key_space(password: &str) -> bool {
|
|||||||
// Create directory if it doesn't exist
|
// Create directory if it doesn't exist
|
||||||
if !key_spaces_dir.exists() {
|
if !key_spaces_dir.exists() {
|
||||||
match fs::create_dir_all(&key_spaces_dir) {
|
match fs::create_dir_all(&key_spaces_dir) {
|
||||||
Ok(_) => {},
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error creating key spaces directory: {}", e);
|
log::error!("Error creating key spaces directory: {}", e);
|
||||||
return false;
|
return false;
|
||||||
@ -191,13 +192,13 @@ fn auto_save_key_space(password: &str) -> bool {
|
|||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
log::info!("Key space saved to {}", space_path.display());
|
log::info!("Key space saved to {}", space_path.display());
|
||||||
true
|
true
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error writing key space file: {}", e);
|
log::error!("Error writing key space file: {}", e);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error getting current space: {}", e);
|
log::error!("Error getting current space: {}", e);
|
||||||
false
|
false
|
||||||
@ -207,22 +208,18 @@ fn auto_save_key_space(password: &str) -> bool {
|
|||||||
|
|
||||||
fn encrypt_key_space(password: &str) -> String {
|
fn encrypt_key_space(password: &str) -> String {
|
||||||
match keypair::get_current_space() {
|
match keypair::get_current_space() {
|
||||||
Ok(space) => {
|
Ok(space) => match symmetric_impl::encrypt_key_space(&space, password) {
|
||||||
match symmetric_impl::encrypt_key_space(&space, password) {
|
Ok(encrypted_space) => match serde_json::to_string(&encrypted_space) {
|
||||||
Ok(encrypted_space) => {
|
|
||||||
match serde_json::to_string(&encrypted_space) {
|
|
||||||
Ok(json) => json,
|
Ok(json) => json,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error serializing encrypted space: {}", e);
|
log::error!("Error serializing encrypted space: {}", e);
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error encrypting key space: {}", e);
|
log::error!("Error encrypting key space: {}", e);
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error getting current space: {}", e);
|
log::error!("Error getting current space: {}", e);
|
||||||
@ -235,21 +232,19 @@ fn decrypt_key_space(encrypted: &str, password: &str) -> bool {
|
|||||||
match serde_json::from_str(encrypted) {
|
match serde_json::from_str(encrypted) {
|
||||||
Ok(encrypted_space) => {
|
Ok(encrypted_space) => {
|
||||||
match symmetric_impl::decrypt_key_space(&encrypted_space, password) {
|
match symmetric_impl::decrypt_key_space(&encrypted_space, password) {
|
||||||
Ok(space) => {
|
Ok(space) => match keypair::set_current_space(space) {
|
||||||
match keypair::set_current_space(space) {
|
|
||||||
Ok(_) => true,
|
Ok(_) => true,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error setting current space: {}", e);
|
log::error!("Error setting current space: {}", e);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error decrypting key space: {}", e);
|
log::error!("Error decrypting key space: {}", e);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error parsing encrypted space: {}", e);
|
log::error!("Error parsing encrypted space: {}", e);
|
||||||
false
|
false
|
||||||
@ -263,7 +258,7 @@ fn create_keypair(name: &str, password: &str) -> bool {
|
|||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
// Auto-save the key space after creating a keypair
|
// Auto-save the key space after creating a keypair
|
||||||
auto_save_key_space(password)
|
auto_save_key_space(password)
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error creating keypair: {}", e);
|
log::error!("Error creating keypair: {}", e);
|
||||||
false
|
false
|
||||||
@ -306,14 +301,12 @@ fn sign(message: &str) -> String {
|
|||||||
fn verify(message: &str, signature: &str) -> bool {
|
fn verify(message: &str, signature: &str) -> bool {
|
||||||
let message_bytes = message.as_bytes();
|
let message_bytes = message.as_bytes();
|
||||||
match BASE64.decode(signature) {
|
match BASE64.decode(signature) {
|
||||||
Ok(signature_bytes) => {
|
Ok(signature_bytes) => match keypair::keypair_verify(message_bytes, &signature_bytes) {
|
||||||
match keypair::keypair_verify(message_bytes, &signature_bytes) {
|
|
||||||
Ok(is_valid) => is_valid,
|
Ok(is_valid) => is_valid,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error verifying signature: {}", e);
|
log::error!("Error verifying signature: {}", e);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error decoding signature: {}", e);
|
log::error!("Error decoding signature: {}", e);
|
||||||
@ -339,7 +332,7 @@ fn encrypt(key: &str, message: &str) -> String {
|
|||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error decoding key: {}", e);
|
log::error!("Error decoding key: {}", e);
|
||||||
String::new()
|
String::new()
|
||||||
@ -349,30 +342,26 @@ fn encrypt(key: &str, message: &str) -> String {
|
|||||||
|
|
||||||
fn decrypt(key: &str, ciphertext: &str) -> String {
|
fn decrypt(key: &str, ciphertext: &str) -> String {
|
||||||
match BASE64.decode(key) {
|
match BASE64.decode(key) {
|
||||||
Ok(key_bytes) => {
|
Ok(key_bytes) => match BASE64.decode(ciphertext) {
|
||||||
match BASE64.decode(ciphertext) {
|
|
||||||
Ok(ciphertext_bytes) => {
|
Ok(ciphertext_bytes) => {
|
||||||
match symmetric_impl::decrypt_symmetric(&key_bytes, &ciphertext_bytes) {
|
match symmetric_impl::decrypt_symmetric(&key_bytes, &ciphertext_bytes) {
|
||||||
Ok(plaintext) => {
|
Ok(plaintext) => match String::from_utf8(plaintext) {
|
||||||
match String::from_utf8(plaintext) {
|
|
||||||
Ok(text) => text,
|
Ok(text) => text,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error converting plaintext to string: {}", e);
|
log::error!("Error converting plaintext to string: {}", e);
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error decrypting ciphertext: {}", e);
|
log::error!("Error decrypting ciphertext: {}", e);
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error decoding ciphertext: {}", e);
|
log::error!("Error decoding ciphertext: {}", e);
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error decoding key: {}", e);
|
log::error!("Error decoding key: {}", e);
|
||||||
@ -478,7 +467,11 @@ fn get_wallet_address_for_network(network_name: &str) -> String {
|
|||||||
match ethereum::get_current_ethereum_wallet_for_network(network_name_proper) {
|
match ethereum::get_current_ethereum_wallet_for_network(network_name_proper) {
|
||||||
Ok(wallet) => wallet.address_string(),
|
Ok(wallet) => wallet.address_string(),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error getting wallet address for network {}: {}", network_name, e);
|
log::error!(
|
||||||
|
"Error getting wallet address for network {}: {}",
|
||||||
|
network_name,
|
||||||
|
e
|
||||||
|
);
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -542,7 +535,11 @@ fn create_wallet_from_private_key_for_network(private_key: &str, network_name: &
|
|||||||
match ethereum::create_ethereum_wallet_from_private_key_for_network(private_key, network) {
|
match ethereum::create_ethereum_wallet_from_private_key_for_network(private_key, network) {
|
||||||
Ok(_) => true,
|
Ok(_) => true,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error creating wallet from private key for network {}: {}", network_name, e);
|
log::error!(
|
||||||
|
"Error creating wallet from private key for network {}: {}",
|
||||||
|
network_name,
|
||||||
|
e
|
||||||
|
);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -563,7 +560,7 @@ fn create_agung_provider() -> String {
|
|||||||
|
|
||||||
log::error!("Failed to acquire provider registry lock");
|
log::error!("Failed to acquire provider registry lock");
|
||||||
String::new()
|
String::new()
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error creating Agung provider: {}", e);
|
log::error!("Error creating Agung provider: {}", e);
|
||||||
String::new()
|
String::new()
|
||||||
@ -619,9 +616,7 @@ fn get_balance(network_name: &str, address: &str) -> String {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Execute the balance query in a blocking manner
|
// Execute the balance query in a blocking manner
|
||||||
match rt.block_on(async {
|
match rt.block_on(async { ethereum::get_balance(&provider, addr).await }) {
|
||||||
ethereum::get_balance(&provider, addr).await
|
|
||||||
}) {
|
|
||||||
Ok(balance) => balance.to_string(),
|
Ok(balance) => balance.to_string(),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Failed to get balance: {}", e);
|
log::error!("Failed to get balance: {}", e);
|
||||||
@ -687,9 +682,7 @@ fn send_eth(wallet_network: &str, to_address: &str, amount_str: &str) -> String
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Execute the transaction in a blocking manner
|
// Execute the transaction in a blocking manner
|
||||||
match rt.block_on(async {
|
match rt.block_on(async { ethereum::send_eth(&wallet, &provider, to_addr, amount).await }) {
|
||||||
ethereum::send_eth(&wallet, &provider, to_addr, amount).await
|
|
||||||
}) {
|
|
||||||
Ok(tx_hash) => format!("{:?}", tx_hash),
|
Ok(tx_hash) => format!("{:?}", tx_hash),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Transaction failed: {}", e);
|
log::error!("Transaction failed: {}", e);
|
||||||
@ -731,7 +724,7 @@ fn load_contract_abi(network_name: &str, address: &str, abi_json: &str) -> Strin
|
|||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error creating contract: {}", e);
|
log::error!("Error creating contract: {}", e);
|
||||||
String::new()
|
String::new()
|
||||||
@ -916,14 +909,20 @@ pub fn register_crypto_module(engine: &mut Engine) -> Result<(), Box<EvalAltResu
|
|||||||
|
|
||||||
// Register generic network functions
|
// Register generic network functions
|
||||||
engine.register_fn("create_wallet_for_network", create_wallet_for_network);
|
engine.register_fn("create_wallet_for_network", create_wallet_for_network);
|
||||||
engine.register_fn("get_wallet_address_for_network", get_wallet_address_for_network);
|
engine.register_fn(
|
||||||
|
"get_wallet_address_for_network",
|
||||||
|
get_wallet_address_for_network,
|
||||||
|
);
|
||||||
engine.register_fn("clear_wallets_for_network", clear_wallets_for_network);
|
engine.register_fn("clear_wallets_for_network", clear_wallets_for_network);
|
||||||
engine.register_fn("list_supported_networks", list_supported_networks);
|
engine.register_fn("list_supported_networks", list_supported_networks);
|
||||||
engine.register_fn("get_network_token_symbol", get_network_token_symbol);
|
engine.register_fn("get_network_token_symbol", get_network_token_symbol);
|
||||||
engine.register_fn("get_network_explorer_url", get_network_explorer_url);
|
engine.register_fn("get_network_explorer_url", get_network_explorer_url);
|
||||||
|
|
||||||
// Register new Ethereum functions for wallet creation from private key and transactions
|
// Register new Ethereum functions for wallet creation from private key and transactions
|
||||||
engine.register_fn("create_wallet_from_private_key_for_network", create_wallet_from_private_key_for_network);
|
engine.register_fn(
|
||||||
|
"create_wallet_from_private_key_for_network",
|
||||||
|
create_wallet_from_private_key_for_network,
|
||||||
|
);
|
||||||
engine.register_fn("create_agung_provider", create_agung_provider);
|
engine.register_fn("create_agung_provider", create_agung_provider);
|
||||||
engine.register_fn("send_eth", send_eth);
|
engine.register_fn("send_eth", send_eth);
|
||||||
engine.register_fn("get_balance", get_balance);
|
engine.register_fn("get_balance", get_balance);
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
use serde::{Serialize, Deserialize};
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use crate::vault::error::CryptoError;
|
use crate::vault::error::CryptoError;
|
||||||
use crate::vault::keypair::keypair_types::{KeyPair, KeySpace}; // Assuming KeyPair and KeySpace will be in keypair_types.rs
|
use crate::vault::keypair::keypair_types::{KeyPair, KeySpace}; // Assuming KeyPair and KeySpace will be in keypair_types.rs
|
||||||
use crate::vault::symmetric; // Assuming symmetric module is needed
|
|
||||||
|
|
||||||
/// Session state for the current key space and selected keypair.
|
/// Session state for the current key space and selected keypair.
|
||||||
pub struct Session {
|
pub struct Session {
|
||||||
@ -23,9 +20,7 @@ impl Default for Session {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Global session state.
|
/// Global session state.
|
||||||
pub static SESSION: Lazy<Mutex<Session>> = Lazy::new(|| {
|
pub static SESSION: Lazy<Mutex<Session>> = Lazy::new(|| Mutex::new(Session::default()));
|
||||||
Mutex::new(Session::default())
|
|
||||||
});
|
|
||||||
|
|
||||||
// Session management and selected keypair operation functions will be added here
|
// Session management and selected keypair operation functions will be added here
|
||||||
/// Creates a new key space with the given name.
|
/// Creates a new key space with the given name.
|
||||||
@ -53,7 +48,10 @@ pub fn set_current_space(space: KeySpace) -> Result<(), CryptoError> {
|
|||||||
/// Gets the current key space.
|
/// Gets the current key space.
|
||||||
pub fn get_current_space() -> Result<KeySpace, CryptoError> {
|
pub fn get_current_space() -> Result<KeySpace, CryptoError> {
|
||||||
let session = SESSION.lock().unwrap();
|
let session = SESSION.lock().unwrap();
|
||||||
session.current_space.clone().ok_or(CryptoError::NoActiveSpace)
|
session
|
||||||
|
.current_space
|
||||||
|
.clone()
|
||||||
|
.ok_or(CryptoError::NoActiveSpace)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears the current session (logout).
|
/// Clears the current session (logout).
|
||||||
@ -152,12 +150,19 @@ pub fn keypair_verify(message: &[u8], signature_bytes: &[u8]) -> Result<bool, Cr
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Verifies a message signature with a public key.
|
/// Verifies a message signature with a public key.
|
||||||
pub fn verify_with_public_key(public_key: &[u8], message: &[u8], signature_bytes: &[u8]) -> Result<bool, CryptoError> {
|
pub fn verify_with_public_key(
|
||||||
|
public_key: &[u8],
|
||||||
|
message: &[u8],
|
||||||
|
signature_bytes: &[u8],
|
||||||
|
) -> Result<bool, CryptoError> {
|
||||||
KeyPair::verify_with_public_key(public_key, message, signature_bytes)
|
KeyPair::verify_with_public_key(public_key, message, signature_bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encrypts a message for a recipient using their public key.
|
/// Encrypts a message for a recipient using their public key.
|
||||||
pub fn encrypt_asymmetric(recipient_public_key: &[u8], message: &[u8]) -> Result<Vec<u8>, CryptoError> {
|
pub fn encrypt_asymmetric(
|
||||||
|
recipient_public_key: &[u8],
|
||||||
|
message: &[u8],
|
||||||
|
) -> Result<Vec<u8>, CryptoError> {
|
||||||
let keypair = get_selected_keypair()?;
|
let keypair = get_selected_keypair()?;
|
||||||
keypair.encrypt_asymmetric(recipient_public_key, message)
|
keypair.encrypt_asymmetric(recipient_public_key, message)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
//! Error types for the key-value store.
|
//! Error types for the key-value store.
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
/// Errors that can occur when using the key-value store.
|
/// Errors that can occur when using the key-value store.
|
||||||
@ -56,7 +55,9 @@ impl From<crate::vault::error::CryptoError> for KvsError {
|
|||||||
match err {
|
match err {
|
||||||
crate::vault::error::CryptoError::EncryptionFailed(msg) => KvsError::Encryption(msg),
|
crate::vault::error::CryptoError::EncryptionFailed(msg) => KvsError::Encryption(msg),
|
||||||
crate::vault::error::CryptoError::DecryptionFailed(msg) => KvsError::Decryption(msg),
|
crate::vault::error::CryptoError::DecryptionFailed(msg) => KvsError::Decryption(msg),
|
||||||
crate::vault::error::CryptoError::SerializationError(msg) => KvsError::Serialization(msg),
|
crate::vault::error::CryptoError::SerializationError(msg) => {
|
||||||
|
KvsError::Serialization(msg)
|
||||||
|
}
|
||||||
_ => KvsError::Other(err.to_string()),
|
_ => KvsError::Other(err.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
//! Implementation of a simple key-value store using the filesystem.
|
//! Implementation of a simple key-value store using the filesystem.
|
||||||
|
|
||||||
use crate::vault::kvs::error::{KvsError, Result};
|
use crate::vault::kvs::error::{KvsError, Result};
|
||||||
use crate::vault::symmetric::implementation::{derive_key_from_password, encrypt_symmetric, decrypt_symmetric};
|
use crate::vault::symmetric::implementation::{
|
||||||
|
decrypt_symmetric, derive_key_from_password, encrypt_symmetric,
|
||||||
|
};
|
||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@ -52,7 +54,9 @@ pub fn get_store_path() -> PathBuf {
|
|||||||
pub fn create_store(name: &str, encrypted: bool, password: Option<&str>) -> Result<KvStore> {
|
pub fn create_store(name: &str, encrypted: bool, password: Option<&str>) -> Result<KvStore> {
|
||||||
// Check if password is provided when encryption is enabled
|
// Check if password is provided when encryption is enabled
|
||||||
if encrypted && password.is_none() {
|
if encrypted && password.is_none() {
|
||||||
return Err(KvsError::Other("Password required for encrypted store".to_string()));
|
return Err(KvsError::Other(
|
||||||
|
"Password required for encrypted store".to_string(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the store directory if it doesn't exist
|
// Create the store directory if it doesn't exist
|
||||||
@ -107,7 +111,9 @@ pub fn open_store(name: &str, password: Option<&str>) -> Result<KvStore> {
|
|||||||
|
|
||||||
// If encrypted, we need a password
|
// If encrypted, we need a password
|
||||||
if is_encrypted && password.is_none() {
|
if is_encrypted && password.is_none() {
|
||||||
return Err(KvsError::Other("Password required for encrypted store".to_string()));
|
return Err(KvsError::Other(
|
||||||
|
"Password required for encrypted store".to_string(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the store data
|
// Parse the store data
|
||||||
@ -115,8 +121,8 @@ pub fn open_store(name: &str, password: Option<&str>) -> Result<KvStore> {
|
|||||||
// Decrypt the file content
|
// Decrypt the file content
|
||||||
let password = password.unwrap();
|
let password = password.unwrap();
|
||||||
let encrypted_data: Vec<u8> = serde_json::from_str(&file_content)?;
|
let encrypted_data: Vec<u8> = serde_json::from_str(&file_content)?;
|
||||||
let key = implementation::derive_key_from_password(password);
|
let key = derive_key_from_password(password);
|
||||||
let decrypted_data = implementation::decrypt_symmetric(&key, &encrypted_data)?;
|
let decrypted_data = decrypt_symmetric(&key, &encrypted_data)?;
|
||||||
let decrypted_str = String::from_utf8(decrypted_data)
|
let decrypted_str = String::from_utf8(decrypted_data)
|
||||||
.map_err(|e| KvsError::Deserialization(e.to_string()))?;
|
.map_err(|e| KvsError::Deserialization(e.to_string()))?;
|
||||||
serde_json::from_str(&decrypted_str)?
|
serde_json::from_str(&decrypted_str)?
|
||||||
@ -203,12 +209,14 @@ impl KvStore {
|
|||||||
if self.encrypted {
|
if self.encrypted {
|
||||||
if let Some(password) = &self.password {
|
if let Some(password) = &self.password {
|
||||||
// Encrypt the data
|
// Encrypt the data
|
||||||
let key = implementation::derive_key_from_password(password);
|
let key = derive_key_from_password(password);
|
||||||
let encrypted_data = implementation::encrypt_symmetric(&key, serialized.as_bytes())?;
|
let encrypted_data = encrypt_symmetric(&key, serialized.as_bytes())?;
|
||||||
let encrypted_json = serde_json::to_string(&encrypted_data)?;
|
let encrypted_json = serde_json::to_string(&encrypted_data)?;
|
||||||
fs::write(&self.path, encrypted_json)?;
|
fs::write(&self.path, encrypted_json)?;
|
||||||
} else {
|
} else {
|
||||||
return Err(KvsError::Other("Password required for encrypted store".to_string()));
|
return Err(KvsError::Other(
|
||||||
|
"Password required for encrypted store".to_string(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fs::write(&self.path, serialized)?;
|
fs::write(&self.path, serialized)?;
|
||||||
@ -268,7 +276,7 @@ impl KvStore {
|
|||||||
Some(serialized) => {
|
Some(serialized) => {
|
||||||
let value: V = serde_json::from_str(serialized)?;
|
let value: V = serde_json::from_str(serialized)?;
|
||||||
Ok(value)
|
Ok(value)
|
||||||
},
|
}
|
||||||
None => Err(KvsError::KeyNotFound(key_str)),
|
None => Err(KvsError::KeyNotFound(key_str)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user