feat: add read/write
This commit is contained in:
110
src/serve_common.rs
Normal file
110
src/serve_common.rs
Normal 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: {}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user