use crate::utils::encryption::{ConnectionStringEncryption, EncryptionError};
use serde::Deserialize;
use std::sync::{Arc, Mutex};
#[derive(Debug, Deserialize, Default, Clone)]
pub struct ServicebusConfig {
encrypted_connection_string: Option<String>,
encryption_salt: Option<String>,
}
static MASTER_PASSWORD: std::sync::OnceLock<Arc<Mutex<Option<String>>>> =
std::sync::OnceLock::new();
impl ServicebusConfig {
pub fn encrypted_connection_string(&self) -> Option<&str> {
self.encrypted_connection_string
.as_deref()
.filter(|s| !s.trim().is_empty())
}
pub fn encryption_salt(&self) -> Option<&str> {
self.encryption_salt
.as_deref()
.filter(|s| !s.trim().is_empty())
}
pub fn connection_string(&self) -> Result<Option<String>, EncryptionError> {
let encrypted = match self.encrypted_connection_string() {
Some(enc) => enc,
None => return Ok(None),
};
let salt = match self.encryption_salt() {
Some(s) => s,
None => {
return Err(EncryptionError::InvalidData(
"Encryption salt not found in configuration".to_string(),
));
}
};
let password = get_master_password().ok_or_else(|| {
EncryptionError::DecryptionFailed(
"Master password not set. Please set password first.".to_string(),
)
})?;
let encryption = ConnectionStringEncryption::from_salt_base64(salt)?;
let decrypted = encryption.decrypt_connection_string(encrypted, &password)?;
Ok(Some(decrypted))
}
pub fn has_connection_string(&self) -> bool {
self.encrypted_connection_string().is_some() && self.encryption_salt().is_some()
}
}
pub fn set_master_password(password: String) {
let password_storage = MASTER_PASSWORD.get_or_init(|| Arc::new(Mutex::new(None)));
if let Ok(mut guard) = password_storage.lock() {
*guard = Some(password);
}
}
pub fn get_master_password() -> Option<String> {
let password_storage = MASTER_PASSWORD.get_or_init(|| Arc::new(Mutex::new(None)));
if let Ok(guard) = password_storage.lock() {
guard.clone()
} else {
None
}
}
pub fn is_master_password_set() -> bool {
get_master_password().is_some()
}
pub fn clear_master_password() {
let password_storage = MASTER_PASSWORD.get_or_init(|| Arc::new(Mutex::new(None)));
if let Ok(mut guard) = password_storage.lock() {
*guard = None;
}
}