feat: add read/write

This commit is contained in:
2023-08-13 15:26:49 +08:00
parent b431a94ef9
commit 167e37f9f8
12 changed files with 439 additions and 245 deletions

110
src/serve_common.rs Normal file
View File

@@ -0,0 +1,110 @@
use std::sync::Mutex;
use base64::Engine;
use base64::engine::general_purpose::STANDARD;
use josekit::jwk::alg::rsa::RsaKeyPair;
use rusqlite::Connection;
use rust_util::{opt_result, simple_error, XResult};
use seckey::SecBytes;
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use crate::db;
pub type GenericError = Box<dyn std::error::Error + Send + Sync>;
pub type Result<T> = std::result::Result<T, GenericError>;
#[macro_export]
macro_rules! do_response {
($ex: expr) => (
match $ex {
Ok((status_code, body)) => Ok(Response::builder().status(status_code).body((serde_json::to_string_pretty(&body)? + "\n").into())?),
Err(e) => Ok(Response::builder().status(StatusCode::INTERNAL_SERVER_ERROR).body(
format!("{}\n", serde_json::to_string_pretty(&json!({
"error": "internal_error",
"error_message": format!("{}", e),
}))?).into()
)?),
}
)
}
pub struct MemoryKey {
pub database_file: String,
pub instance_rsa_key_pair: RsaKeyPair,
pub master_key: Option<SecBytes>,
}
lazy_static::lazy_static! {
pub static ref STATUP_RW_LOCK: Mutex<Option<MemoryKey>> = Mutex::new(None);
}
#[derive(Serialize, Deserialize)]
pub struct MultipleViewValue {
pub value: Option<String>,
pub value_hex: Option<String>,
pub value_base64: Option<String>,
}
impl MultipleViewValue {
pub fn from(v: &[u8]) -> Self {
Self {
value: Some(String::from_utf8_lossy(v).to_string()),
value_hex: Some(hex::encode(v)),
value_base64: Some(STANDARD.encode(v)),
}
}
pub fn to_bytes(&self) -> XResult<Vec<u8>> {
if let Some(v) = &self.value {
Ok(v.as_bytes().to_vec())
} else if let Some(v) = &self.value_hex {
let v = opt_result!(hex::decode(v), "Decode hex failed: {}");
Ok(v)
} else if let Some(v) = &self.value_base64 {
let v = opt_result!(STANDARD.decode(v), "Decode base64 failed: {}");
Ok(v)
} else {
simple_error!("Multiple view value is all empty")
}
}
}
pub fn get_master_key() -> Option<SecBytes> {
let startup_rw_lock = STATUP_RW_LOCK.lock().expect("Lock read startup rw lock error");
match &*startup_rw_lock {
None => None,
Some(k) => match &k.master_key {
None => None,
Some(k) => {
let k = &*k.read();
Some(SecBytes::with(k.len(), |buf| buf.copy_from_slice(k)))
}
},
}
}
pub fn byte_to_multi_view_map(bytes: &[u8]) -> Map<String, Value> {
let v = MultipleViewValue::from(bytes);
let mut map = Map::new();
if let Some(v) = &v.value {
map.insert("value".to_string(), Value::String(v.to_string()));
}
if let Some(v) = &v.value_hex {
map.insert("value_hex".to_string(), Value::String(v.to_string()));
}
if let Some(v) = &v.value_base64 {
map.insert("value_base64".to_string(), Value::String(v.to_string()));
}
map
}
pub fn open_local_db() -> XResult<Connection> {
let startup_rw_lock = STATUP_RW_LOCK.lock().expect("Lock read startup rw lock error");
match &*startup_rw_lock {
None => simple_error!("Db is not initted!"),
Some(k) => {
Ok(opt_result!(db::open_db(& k.database_file), "Open db failed: {}"))
}
}
}