fix bug where meta files where not auto-created upon starting + fix bug where meta json files were actually binary + improved access control to database instances
This commit is contained in:
@@ -76,9 +76,12 @@ async fn main() {
|
||||
// new server
|
||||
let mut server = server::Server::new(option).await;
|
||||
|
||||
// Initialize the default database storage
|
||||
// Initialize the default database storage (creates 0.db)
|
||||
let _ = server.current_storage();
|
||||
|
||||
// Ensure default meta for DB 0 exists (public by default if missing)
|
||||
let _ = herodb::rpc::RpcServerImpl::load_meta_static(&server.option.dir, 0).await;
|
||||
|
||||
// Add a small delay to ensure the port is ready
|
||||
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
||||
|
||||
|
96
src/rpc.rs
96
src/rpc.rs
@@ -239,29 +239,25 @@ impl RpcServerImpl {
|
||||
pub async fn load_meta_static(base_dir: &str, db_id: u64) -> Result<DatabaseMeta, jsonrpsee::types::ErrorObjectOwned> {
|
||||
let meta_path = std::path::PathBuf::from(base_dir).join(format!("{}_meta.json", db_id));
|
||||
|
||||
// If meta file doesn't exist, return default
|
||||
// If meta file doesn't exist, create and persist default
|
||||
if !meta_path.exists() {
|
||||
return Ok(DatabaseMeta {
|
||||
let default_meta = DatabaseMeta {
|
||||
public: true,
|
||||
keys: HashMap::new(),
|
||||
});
|
||||
};
|
||||
// Persist default metadata to disk
|
||||
Self::save_meta_static(base_dir, db_id, &default_meta).await?;
|
||||
return Ok(default_meta);
|
||||
}
|
||||
|
||||
// Read file
|
||||
let content = std::fs::read(&meta_path)
|
||||
// Read file as UTF-8 JSON
|
||||
let json_str = std::fs::read_to_string(&meta_path)
|
||||
.map_err(|e| jsonrpsee::types::ErrorObjectOwned::owned(
|
||||
-32000,
|
||||
format!("Failed to read meta file: {}", e),
|
||||
None::<()>
|
||||
))?;
|
||||
|
||||
let json_str = String::from_utf8(content)
|
||||
.map_err(|_| jsonrpsee::types::ErrorObjectOwned::owned(
|
||||
-32000,
|
||||
"Invalid UTF-8 in meta file",
|
||||
None::<()>
|
||||
))?;
|
||||
|
||||
serde_json::from_str(&json_str)
|
||||
.map_err(|e| jsonrpsee::types::ErrorObjectOwned::owned(
|
||||
-32000,
|
||||
@@ -274,7 +270,7 @@ impl RpcServerImpl {
|
||||
async fn load_meta(&self, db_id: u64) -> Result<DatabaseMeta, jsonrpsee::types::ErrorObjectOwned> {
|
||||
let meta_path = std::path::PathBuf::from(&self.base_dir).join(format!("{}_meta.json", db_id));
|
||||
|
||||
// If meta file doesn't exist, create default
|
||||
// If meta file doesn't exist, create and persist default
|
||||
if !meta_path.exists() {
|
||||
let default_meta = DatabaseMeta {
|
||||
public: true,
|
||||
@@ -284,46 +280,14 @@ impl RpcServerImpl {
|
||||
return Ok(default_meta);
|
||||
}
|
||||
|
||||
// Read and potentially decrypt
|
||||
let content = std::fs::read(&meta_path)
|
||||
// Read file as UTF-8 JSON (meta files are always plain JSON)
|
||||
let json_str = std::fs::read_to_string(&meta_path)
|
||||
.map_err(|e| jsonrpsee::types::ErrorObjectOwned::owned(
|
||||
-32000,
|
||||
format!("Failed to read meta file: {}", e),
|
||||
None::<()>
|
||||
))?;
|
||||
|
||||
let json_str = if db_id >= 10 {
|
||||
// Encrypted database, decrypt meta
|
||||
if let Some(key) = self.encryption_keys.read().await.get(&db_id).and_then(|k| k.as_ref()) {
|
||||
use crate::crypto::CryptoFactory;
|
||||
let crypto = CryptoFactory::new(key.as_bytes());
|
||||
String::from_utf8(crypto.decrypt(&content)
|
||||
.map_err(|_| jsonrpsee::types::ErrorObjectOwned::owned(
|
||||
-32000,
|
||||
"Failed to decrypt meta file",
|
||||
None::<()>
|
||||
))?)
|
||||
.map_err(|_| jsonrpsee::types::ErrorObjectOwned::owned(
|
||||
-32000,
|
||||
"Invalid UTF-8 in decrypted meta",
|
||||
None::<()>
|
||||
))?
|
||||
} else {
|
||||
return Err(jsonrpsee::types::ErrorObjectOwned::owned(
|
||||
-32000,
|
||||
"Encryption key not found for encrypted database",
|
||||
None::<()>
|
||||
));
|
||||
}
|
||||
} else {
|
||||
String::from_utf8(content)
|
||||
.map_err(|_| jsonrpsee::types::ErrorObjectOwned::owned(
|
||||
-32000,
|
||||
"Invalid UTF-8 in meta file",
|
||||
None::<()>
|
||||
))?
|
||||
};
|
||||
|
||||
serde_json::from_str(&json_str)
|
||||
.map_err(|e| jsonrpsee::types::ErrorObjectOwned::owned(
|
||||
-32000,
|
||||
@@ -336,7 +300,7 @@ impl RpcServerImpl {
|
||||
pub async fn save_meta_static(base_dir: &str, db_id: u64, meta: &DatabaseMeta) -> Result<(), jsonrpsee::types::ErrorObjectOwned> {
|
||||
let meta_path = std::path::PathBuf::from(base_dir).join(format!("{}_meta.json", db_id));
|
||||
|
||||
let json_str = serde_json::to_string(meta)
|
||||
let json_str = serde_json::to_string_pretty(meta)
|
||||
.map_err(|e| jsonrpsee::types::ErrorObjectOwned::owned(
|
||||
-32000,
|
||||
format!("Failed to serialize meta: {}", e),
|
||||
@@ -357,40 +321,20 @@ impl RpcServerImpl {
|
||||
async fn save_meta(&self, db_id: u64, meta: &DatabaseMeta) -> Result<(), jsonrpsee::types::ErrorObjectOwned> {
|
||||
let meta_path = std::path::PathBuf::from(&self.base_dir).join(format!("{}_meta.json", db_id));
|
||||
|
||||
let json_str = serde_json::to_string(meta)
|
||||
let json_str = serde_json::to_string_pretty(meta)
|
||||
.map_err(|e| jsonrpsee::types::ErrorObjectOwned::owned(
|
||||
-32000,
|
||||
format!("Failed to serialize meta: {}", e),
|
||||
None::<()>
|
||||
))?;
|
||||
|
||||
if db_id >= 10 {
|
||||
// Encrypted database, encrypt meta
|
||||
if let Some(key) = self.encryption_keys.read().await.get(&db_id).and_then(|k| k.as_ref()) {
|
||||
use crate::crypto::CryptoFactory;
|
||||
let crypto = CryptoFactory::new(key.as_bytes());
|
||||
let encrypted = crypto.encrypt(json_str.as_bytes());
|
||||
std::fs::write(&meta_path, encrypted)
|
||||
.map_err(|e| jsonrpsee::types::ErrorObjectOwned::owned(
|
||||
-32000,
|
||||
format!("Failed to write encrypted meta file: {}", e),
|
||||
None::<()>
|
||||
))?;
|
||||
} else {
|
||||
return Err(jsonrpsee::types::ErrorObjectOwned::owned(
|
||||
-32000,
|
||||
"Encryption key not found for encrypted database",
|
||||
None::<()>
|
||||
));
|
||||
}
|
||||
} else {
|
||||
std::fs::write(&meta_path, json_str)
|
||||
.map_err(|e| jsonrpsee::types::ErrorObjectOwned::owned(
|
||||
-32000,
|
||||
format!("Failed to write meta file: {}", e),
|
||||
None::<()>
|
||||
))?;
|
||||
}
|
||||
// Meta files are always stored as plain JSON (even when data DB is encrypted)
|
||||
std::fs::write(&meta_path, json_str)
|
||||
.map_err(|e| jsonrpsee::types::ErrorObjectOwned::owned(
|
||||
-32000,
|
||||
format!("Failed to write meta file: {}", e),
|
||||
None::<()>
|
||||
))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
Reference in New Issue
Block a user