diff --git a/bin/Cargo.lock b/bin/Cargo.lock index 9dc6c39..425b0ae 100644 --- a/bin/Cargo.lock +++ b/bin/Cargo.lock @@ -1594,6 +1594,7 @@ dependencies = [ "serde_bencode", "serde_json", "sqlite", + "thiserror", "trust-graph", ] diff --git a/bin/Cargo.toml b/bin/Cargo.toml index 51ff958..0c614ca 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -26,3 +26,4 @@ rmp-serde = "0.15.0" bincode = "1.3.1" serde_bencode = "^0.2.3" sqlite = "0.25.3" +thiserror = "1.0.23" diff --git a/bin/src/service_api.rs b/bin/src/service_api.rs index fbaee3b..5ba6d5f 100644 --- a/bin/src/service_api.rs +++ b/bin/src/service_api.rs @@ -25,19 +25,6 @@ fn insert_cert(certificate: String, duration: u64) -> InsertResult { } } -#[fce] -fn looper() { - - let second = std::time::Duration::from_millis(1000); - - let mut a = 0; - while true { - std::thread::sleep(second); - a = a + 1; - log::info!("{}", a) - } -} - #[fce] fn test() -> String { let mut tg = get_data().lock(); diff --git a/bin/src/storage_impl.rs b/bin/src/storage_impl.rs index f672bce..3ce2ef8 100644 --- a/bin/src/storage_impl.rs +++ b/bin/src/storage_impl.rs @@ -9,14 +9,19 @@ use parking_lot::Mutex; use fce_sqlite_connector; use fce_sqlite_connector::Connection; use fce_sqlite_connector::Value; +use fce_sqlite_connector::Error as InternalSqliteError; use std::str::FromStr; use std::time::Duration; -use trust_graph::{Auth, PublicKeyHashable, Revoke, Storage, TrustGraph, TrustNode, Weight}; -use std::ops::Deref; +use trust_graph::{Auth, PublicKeyHashable, Revoke, Storage, TrustGraph, TrustNode, Weight, StorageError}; +use thiserror::Error as ThisError; +use crate::storage_impl::SqliteStorageError::{SqliteError, EncodeError, ConvertionError, DecodeError, Unexpected, RevokeError}; +use rmp_serde::encode::Error as RmpEncodeError; +use rmp_serde::decode::Error as RmpDecodeError; +use std::convert::From; -static INSTANCE: OnceCell> = OnceCell::new(); +static INSTANCE: OnceCell>> = OnceCell::new(); -pub fn get_data() -> &'static Mutex { +pub fn get_data() -> &'static Mutex> { INSTANCE.get_or_init(|| { let db_path = "/tmp/users123123.sqlite"; let connection = fce_sqlite_connector::open(db_path).unwrap(); @@ -46,127 +51,163 @@ impl SqliteStorage { } } +#[derive(ThisError, Debug)] +pub enum SqliteStorageError { + #[error("Unexpected: {0}")] + Unexpected(String), + #[error("{0}")] + SqliteError(InternalSqliteError), + #[error("{0}")] + EncodeError(String), + #[error("{0}")] + DecodeError(String), + #[error("There is no entry for {0}")] + ConvertionError(String), + #[error("Cannot revoke a trust: {0}")] + RevokeError(String) +} + +impl From for SqliteStorageError { + fn from(err: InternalSqliteError) -> Self { + SqliteError(err) + } +} + +impl From for SqliteStorageError { + fn from(err: RmpEncodeError) -> Self { + EncodeError(format!("{}", err)) + } +} + +impl From for SqliteStorageError { + fn from(err: RmpDecodeError) -> Self { + DecodeError(format!("{}", err)) + } +} + +impl From for String { + fn from(err: SqliteStorageError) -> Self { + err.into() + } +} + +impl StorageError for SqliteStorageError {} + impl Storage for SqliteStorage { - fn get(&self, pk: &PublicKeyHashable) -> Option { + + type Error = SqliteStorageError; + + fn get(&self, pk: &PublicKeyHashable) -> Result, Self::Error> { let mut cursor = self .connection - .prepare("SELECT trustnode FROM trustnodes WHERE public_key = ?") - .expect("unexpected: 'get' request should be correct") + .prepare("SELECT trustnode FROM trustnodes WHERE public_key = ?")? .cursor(); cursor - .bind(&[Value::String(format!("{}", pk))]) - .expect("unexpected: 'public_key' field should be string"); + .bind(&[Value::String(format!("{}", pk))])?; match cursor.next().unwrap() { Some(r) => { log::info!("row: {:?}", r); let tn_bin: &[u8] = r[0] - .as_binary() - .expect("unexpected: 'trustnode' in a table should be as binary"); + .as_binary().ok_or(ConvertionError("cannot get trustnode as binary".to_string()))?; log::info!("binary: {:?}", tn_bin); - let trust_node: TrustNode = rmp_serde::from_read_ref(tn_bin) - // let trust_node: TrustNode = bincode::deserialize(tn_bin) - // let trust_node: TrustNode = serde_bencode::de::from_bytes(tn_bin) - .expect("unexpected: 'trustnode' should be as correct binary"); + let trust_node: TrustNode = rmp_serde::from_read_ref(tn_bin)?; log::info!("trustnode: {:?}", trust_node); - Some(trust_node) + Ok(Some(trust_node)) } - None => None, + None => Ok(None), } } - fn insert(&mut self, pk: PublicKeyHashable, node: TrustNode) { + fn insert(&mut self, pk: PublicKeyHashable, node: TrustNode) -> Result<(), Self::Error> { let mut cursor = self .connection - .prepare("INSERT OR REPLACE INTO trustnodes VALUES (?, ?)") - .unwrap() + .prepare("INSERT OR REPLACE INTO trustnodes VALUES (?, ?)")? .cursor(); - let tn_vec = rmp_serde::to_vec(&node).unwrap(); - // let tn_vec = bincode::serialize(&node).unwrap(); - let tn_vec = serde_bencode::to_bytes(&node).unwrap(); + let tn_vec = rmp_serde::to_vec(&node)?; log::info!("insert: {:?}", tn_vec); cursor - .bind(&[Value::String(format!("{}", pk)), Value::Binary(tn_vec)]) - .unwrap(); + .bind(&[Value::String(format!("{}", pk)), Value::Binary(tn_vec)])?; - cursor.next().unwrap(); + cursor.next()?; + Ok({}) } - fn get_root_weight(&self, pk: &PublicKeyHashable) -> Option { + fn get_root_weight(&self, pk: &PublicKeyHashable) -> Result, Self::Error> { let mut cursor = self .connection - .prepare("SELECT public_key,weight FROM roots WHERE public_key = ?") - .unwrap() + .prepare("SELECT public_key,weight FROM roots WHERE public_key = ?")? .cursor(); - cursor.bind(&[Value::String(format!("{}", pk))]).unwrap(); + cursor.bind(&[Value::String(format!("{}", pk))])?; - if let Some(row) = cursor.next().unwrap() { + if let Some(row) = cursor.next()? { log::info!("row: {:?}", row); - let w = u32::try_from(row[1].as_integer().unwrap()).unwrap(); + let w = u32::try_from(row[1].as_integer().ok_or(ConvertionError("cannot get weight as integer".to_string()))?) + .map_err(|e| Unexpected(format!("Unexpected. Cannot convert weight to u32: {}", e)))?; - Some(w) + Ok(Some(w)) } else { - None + Ok(None) } } - fn add_root_weight(&mut self, pk: PublicKeyHashable, weight: Weight) { + fn add_root_weight(&mut self, pk: PublicKeyHashable, weight: Weight) -> Result<(), Self::Error> { log::info!("add root: {} weight: {}", pk, weight); let mut cursor = self .connection - .prepare("INSERT OR REPLACE INTO roots VALUES (?, ?)") - .unwrap() + .prepare("INSERT OR REPLACE INTO roots VALUES (?, ?)")? .cursor(); cursor .bind(&[ Value::String(format!("{}", pk)), Value::Integer(i64::from(weight)), - ]) - .unwrap(); + ])?; - cursor.next().unwrap(); + cursor.next()?; + Ok({}) } - fn root_keys(&self) -> Vec { + fn root_keys(&self) -> Result, Self::Error> { let mut cursor = self .connection - .prepare("SELECT public_key,weight FROM roots") - .unwrap() + .prepare("SELECT public_key,weight FROM roots")? .cursor(); let mut roots = vec![]; - while let Some(row) = cursor.next().unwrap() { + while let Some(row) = cursor.next()? { log::info!("row: {:?}", row); + let pk = row[0].as_string() + .ok_or(ConvertionError("cannot get public key as binary".to_string()))?; let pk: PublicKeyHashable = - PublicKeyHashable::from_str(row[0].as_string().unwrap()).unwrap(); + PublicKeyHashable::from_str(pk).map_err(|e| DecodeError(e.to_string()))?; roots.push(pk) } - roots + Ok(roots) } - fn revoke(&mut self, pk: &PublicKeyHashable, revoke: Revoke) -> Result<(), String> { - match self.get(&pk) { + fn revoke(&mut self, pk: &PublicKeyHashable, revoke: Revoke) -> Result<(), Self::Error> { + match self.get(&pk)? { Some(mut trust_node) => { trust_node.update_revoke(revoke); - self.insert(pk.clone(), trust_node); + self.insert(pk.clone(), trust_node)?; Ok(()) } - None => Err("There is no trust with such PublicKey".to_string()), + None => Err(RevokeError("There is no trust with such PublicKey".to_string())), } } @@ -176,8 +217,8 @@ impl Storage for SqliteStorage { auth: Auth, issued_for: &PublicKey, cur_time: Duration, - ) { - match self.get(&pk) { + ) -> Result<(), Self::Error> { + match self.get(&pk)? { Some(mut trust_node) => { trust_node.update_auth(auth); self.insert(pk.clone(), trust_node) @@ -185,7 +226,7 @@ impl Storage for SqliteStorage { None => { let mut trust_node = TrustNode::new(issued_for.clone(), cur_time); trust_node.update_auth(auth); - self.insert(pk.clone(), trust_node); + self.insert(pk.clone(), trust_node) } } } diff --git a/src/certificate.rs b/src/certificate.rs index ab92c9b..ecd7d39 100644 --- a/src/certificate.rs +++ b/src/certificate.rs @@ -42,7 +42,7 @@ pub struct Certificate { pub enum CerificateError { #[error("Error while decoding a certificate: {0}")] DecodeError(String), - #[error("Certificate is expired. Issued at {issued_at:?} and expired at {expires_at:?}")] + #[error("Certificate is expired. Issued at {issued_at} and expired at {expires_at}")] ExpirationError { expires_at: String, issued_at: String, diff --git a/src/lib.rs b/src/lib.rs index 6b73d6e..bd09408 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,5 +42,5 @@ pub use crate::public_key_hashable::PublicKeyHashable; pub use crate::revoke::Revoke; pub use crate::trust::Trust; pub use crate::trust_graph::{TrustGraph, Weight}; -pub use crate::trust_graph_storage::Storage; +pub use crate::trust_graph_storage::{Storage, StorageError}; pub use crate::trust_node::{Auth, TrustNode}; diff --git a/src/trust_graph_storage.rs b/src/trust_graph_storage.rs index d37c9db..ffa19c3 100644 --- a/src/trust_graph_storage.rs +++ b/src/trust_graph_storage.rs @@ -119,7 +119,7 @@ impl Storage for InMemoryStorage { auth: Auth, issued_for: &PublicKey, cur_time: Duration, - ) -> Result<(), InMemoryStorageError> { + ) -> Result<(), Self::Error> { match self.nodes.get_mut(&pk) { Some(trust_node) => { trust_node.update_auth(auth);