mirror of
https://github.com/fluencelabs/trust-graph
synced 2025-04-25 07:42:14 +00:00
rename dir, restruct all errors
This commit is contained in:
parent
61fd3cb312
commit
b10726032e
@ -15,10 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::certificate::CertificateError::{
|
use crate::certificate::CertificateError::{
|
||||||
CertificateLengthError, DecodeError, ExpirationError, KeyInCertificateError, MalformedRoot,
|
CertificateLengthError, DecodeError, DecodeTrustError, ExpirationError, IncorrectByteLength,
|
||||||
NoTrustedRoot, VerificationError,
|
IncorrectCertificateFormat, KeyInCertificateError, MalformedRoot, NoTrustedRoot,
|
||||||
|
VerificationError,
|
||||||
};
|
};
|
||||||
use crate::trust::{Trust, TRUST_LEN};
|
use crate::trust::{Trust, TrustError, TRUST_LEN};
|
||||||
use fluence_identity::key_pair::KeyPair;
|
use fluence_identity::key_pair::KeyPair;
|
||||||
use fluence_identity::public_key::PublicKey;
|
use fluence_identity::public_key::PublicKey;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
@ -40,8 +41,12 @@ pub struct Certificate {
|
|||||||
|
|
||||||
#[derive(ThisError, Debug)]
|
#[derive(ThisError, Debug)]
|
||||||
pub enum CertificateError {
|
pub enum CertificateError {
|
||||||
#[error("Error while decoding a certificate: {0}")]
|
#[error("Incorrect format of the certificate: {0}")]
|
||||||
DecodeError(String),
|
IncorrectCertificateFormat(String),
|
||||||
|
#[error("Incorrect length of an array. Should be 2 bytes of a format, 4 bytes of a version and 104 bytes for each trust")]
|
||||||
|
IncorrectByteLength,
|
||||||
|
#[error("Error while decoding a trust in a certificate: {0}")]
|
||||||
|
DecodeError(TrustError),
|
||||||
#[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 {
|
ExpirationError {
|
||||||
expires_at: String,
|
expires_at: String,
|
||||||
@ -50,21 +55,17 @@ pub enum CertificateError {
|
|||||||
#[error("Certificate does not contain a trusted root.")]
|
#[error("Certificate does not contain a trusted root.")]
|
||||||
NoTrustedRoot,
|
NoTrustedRoot,
|
||||||
#[error("Root trust did not pass verification: {0}")]
|
#[error("Root trust did not pass verification: {0}")]
|
||||||
MalformedRoot(String),
|
MalformedRoot(TrustError),
|
||||||
#[error("There is no `issued_by` public key in a certificate")]
|
#[error("There is no `issued_by` public key in a certificate")]
|
||||||
KeyInCertificateError,
|
KeyInCertificateError,
|
||||||
#[error("The certificate must have at least 1 trust")]
|
#[error("The certificate must have at least 1 trust")]
|
||||||
CertificateLengthError,
|
CertificateLengthError,
|
||||||
|
#[error("Cannot convert trust number {0} from string: {1}")]
|
||||||
|
DecodeTrustError(usize, TrustError),
|
||||||
#[error("Trust {0} in chain did not pass verification: {1}")]
|
#[error("Trust {0} in chain did not pass verification: {1}")]
|
||||||
VerificationError(usize, String),
|
VerificationError(usize, TrustError),
|
||||||
#[error("Unexpected error: {0}")]
|
#[error("there cannot be paths without any nodes after adding verified certificates")]
|
||||||
Unexpected(String),
|
Unexpected,
|
||||||
}
|
|
||||||
|
|
||||||
impl From<CertificateError> for String {
|
|
||||||
fn from(err: CertificateError) -> Self {
|
|
||||||
format!("{}", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Certificate {
|
impl Certificate {
|
||||||
@ -156,8 +157,7 @@ impl Certificate {
|
|||||||
|
|
||||||
// check root trust and its existence in trusted roots list
|
// check root trust and its existence in trusted roots list
|
||||||
let root = &chain[0];
|
let root = &chain[0];
|
||||||
Trust::verify(root, &root.issued_for, cur_time)
|
Trust::verify(root, &root.issued_for, cur_time).map_err(|e| MalformedRoot(e))?;
|
||||||
.map_err(|e| MalformedRoot(format!("{}", e)))?;
|
|
||||||
if !trusted_roots.contains(&root.issued_for) {
|
if !trusted_roots.contains(&root.issued_for) {
|
||||||
return Err(NoTrustedRoot);
|
return Err(NoTrustedRoot);
|
||||||
}
|
}
|
||||||
@ -169,7 +169,7 @@ impl Certificate {
|
|||||||
let trust_giver = &chain[trust_id - 1];
|
let trust_giver = &chain[trust_id - 1];
|
||||||
|
|
||||||
Trust::verify(trust, &trust_giver.issued_for, cur_time)
|
Trust::verify(trust, &trust_giver.issued_for, cur_time)
|
||||||
.map_err(|e| VerificationError(trust_id, format!("{}", e)))?;
|
.map_err(|e| VerificationError(trust_id, e))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -195,7 +195,7 @@ impl Certificate {
|
|||||||
pub fn decode(arr: &[u8]) -> Result<Self, CertificateError> {
|
pub fn decode(arr: &[u8]) -> Result<Self, CertificateError> {
|
||||||
let trusts_offset = arr.len() - 2 - 4;
|
let trusts_offset = arr.len() - 2 - 4;
|
||||||
if trusts_offset % TRUST_LEN != 0 {
|
if trusts_offset % TRUST_LEN != 0 {
|
||||||
return Err(DecodeError("Incorrect length of an array. Should be 2 bytes of a format, 4 bytes of a version and 104 bytes for each trust. ".to_string()));
|
return Err(IncorrectByteLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
let number_of_trusts = trusts_offset / TRUST_LEN;
|
let number_of_trusts = trusts_offset / TRUST_LEN;
|
||||||
@ -214,7 +214,7 @@ impl Certificate {
|
|||||||
let from = i * TRUST_LEN + 6;
|
let from = i * TRUST_LEN + 6;
|
||||||
let to = (i + 1) * TRUST_LEN + 6;
|
let to = (i + 1) * TRUST_LEN + 6;
|
||||||
let slice = &arr[from..to];
|
let slice = &arr[from..to];
|
||||||
let t = Trust::decode(slice).map_err(|e| DecodeError(format!("{}", e)))?;
|
let t = Trust::decode(slice).map_err(|e| DecodeError(e))?;
|
||||||
chain.push(t);
|
chain.push(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,10 +244,7 @@ impl FromStr for Certificate {
|
|||||||
let _version = str_lines[1];
|
let _version = str_lines[1];
|
||||||
|
|
||||||
if (str_lines.len() - 2) % 4 != 0 {
|
if (str_lines.len() - 2) % 4 != 0 {
|
||||||
return Err(DecodeError(format!(
|
return Err(IncorrectCertificateFormat(s.to_string()));
|
||||||
"Incorrect format of the certificate: {}",
|
|
||||||
s
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let num_of_trusts = (str_lines.len() - 2) / 4;
|
let num_of_trusts = (str_lines.len() - 2) / 4;
|
||||||
@ -260,12 +257,7 @@ impl FromStr for Certificate {
|
|||||||
str_lines[i + 2],
|
str_lines[i + 2],
|
||||||
str_lines[i + 3],
|
str_lines[i + 3],
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| DecodeTrustError(i, e))?;
|
||||||
DecodeError(format!(
|
|
||||||
"Cannot convert trust number {} from string: {}",
|
|
||||||
i, e
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
trusts.push(trust);
|
trusts.push(trust);
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
use fluence_identity::public_key::PublicKey;
|
use fluence_identity::public_key::PublicKey;
|
||||||
|
|
||||||
|
use crate::public_key_hashable::PkError::{Base58DecodeError, BytesDecodeError};
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
use ed25519_dalek::SignatureError;
|
||||||
use ref_cast::RefCast;
|
use ref_cast::RefCast;
|
||||||
use serde::ser::Serializer;
|
use serde::ser::Serializer;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
@ -24,6 +26,7 @@ use std::{
|
|||||||
fmt::{Display, Formatter},
|
fmt::{Display, Formatter},
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
};
|
};
|
||||||
|
use thiserror::Error as ThisError;
|
||||||
|
|
||||||
/// Wrapper to use PublicKey in HashMap
|
/// Wrapper to use PublicKey in HashMap
|
||||||
#[derive(PartialEq, Eq, Debug, Clone, RefCast)]
|
#[derive(PartialEq, Eq, Debug, Clone, RefCast)]
|
||||||
@ -81,16 +84,23 @@ impl Display for PublicKeyHashable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(ThisError, Debug)]
|
||||||
|
pub enum PkError {
|
||||||
|
#[error("Invalid string '{0}': {1}")]
|
||||||
|
Base58DecodeError(String, bs58::decode::Error),
|
||||||
|
#[error("Invalid bytes {0:?}: {1}")]
|
||||||
|
BytesDecodeError(Vec<u8>, SignatureError),
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for PublicKeyHashable {
|
impl FromStr for PublicKeyHashable {
|
||||||
type Err = String;
|
type Err = PkError;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
let bytes = bs58::decode(s)
|
let bytes = bs58::decode(s)
|
||||||
.into_vec()
|
.into_vec()
|
||||||
.map_err(|err| format!("Invalid string '{}': {}", s, err))?;
|
.map_err(|err| Base58DecodeError(s.to_string(), err))?;
|
||||||
|
|
||||||
let pk = PublicKey::from_bytes(&bytes)
|
let pk = PublicKey::from_bytes(&bytes).map_err(|err| BytesDecodeError(bytes, err))?;
|
||||||
.map_err(|err| format!("Invalid bytes {:?}: {}", bytes, err))?;
|
|
||||||
Ok(PublicKeyHashable::from(pk))
|
Ok(PublicKeyHashable::from(pk))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,11 +64,11 @@ pub enum TrustError {
|
|||||||
Expired(Duration, Duration),
|
Expired(Duration, Duration),
|
||||||
|
|
||||||
/// Errors occured on signature verification
|
/// Errors occured on signature verification
|
||||||
#[error("{0:?}")]
|
#[error("{0}")]
|
||||||
SignatureError(String),
|
SignatureError(String),
|
||||||
|
|
||||||
/// Errors occured on trust decoding from differrent formats
|
/// Errors occured on trust decoding from differrent formats
|
||||||
#[error("{0:?}")]
|
#[error("{0}")]
|
||||||
DecodeError(String),
|
DecodeError(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,10 +21,11 @@ use crate::revoke::Revoke;
|
|||||||
use crate::revoke::RevokeError;
|
use crate::revoke::RevokeError;
|
||||||
use crate::trust::Trust;
|
use crate::trust::Trust;
|
||||||
use crate::trust_graph::TrustGraphError::{
|
use crate::trust_graph::TrustGraphError::{
|
||||||
CertificateCheckError, InternalStorageError, NoRoot, RevokeCheckError,
|
CertificateCheckError, EmptyChain, InternalStorageError, NoRoot, RevokeCheckError,
|
||||||
};
|
};
|
||||||
use crate::trust_graph_storage::Storage;
|
use crate::trust_graph_storage::Storage;
|
||||||
use crate::trust_node::{Auth, TrustNode};
|
use crate::trust_node::{Auth, TrustNode};
|
||||||
|
use crate::StorageError;
|
||||||
use fluence_identity::public_key::PublicKey;
|
use fluence_identity::public_key::PublicKey;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::collections::{HashSet, VecDeque};
|
use std::collections::{HashSet, VecDeque};
|
||||||
@ -50,15 +51,23 @@ where
|
|||||||
#[derive(ThisError, Debug)]
|
#[derive(ThisError, Debug)]
|
||||||
pub enum TrustGraphError {
|
pub enum TrustGraphError {
|
||||||
#[error("Internal storage error: {0}")]
|
#[error("Internal storage error: {0}")]
|
||||||
InternalStorageError(String),
|
InternalStorageError(Box<dyn StorageError>),
|
||||||
#[error("There is no root for this certificate.")]
|
#[error("There is no root for this certificate.")]
|
||||||
NoRoot,
|
NoRoot,
|
||||||
|
#[error("Chain is empty")]
|
||||||
|
EmptyChain,
|
||||||
#[error("Certificate check error: {0}")]
|
#[error("Certificate check error: {0}")]
|
||||||
CertificateCheckError(CertificateError),
|
CertificateCheckError(CertificateError),
|
||||||
#[error("Error on revoking a trust: {0}")]
|
#[error("Error on revoking a trust: {0}")]
|
||||||
RevokeCheckError(RevokeError),
|
RevokeCheckError(RevokeError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: StorageError + 'static> From<T> for TrustGraphError {
|
||||||
|
fn from(err: T) -> Self {
|
||||||
|
InternalStorageError(Box::new(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<CertificateError> for TrustGraphError {
|
impl From<CertificateError> for TrustGraphError {
|
||||||
fn from(err: CertificateError) -> Self {
|
fn from(err: CertificateError) -> Self {
|
||||||
CertificateCheckError(err)
|
CertificateCheckError(err)
|
||||||
@ -92,16 +101,12 @@ where
|
|||||||
pk: PublicKeyHashable,
|
pk: PublicKeyHashable,
|
||||||
weight: Weight,
|
weight: Weight,
|
||||||
) -> Result<(), TrustGraphError> {
|
) -> Result<(), TrustGraphError> {
|
||||||
self.storage
|
Ok(self.storage.add_root_weight(pk, weight)?)
|
||||||
.add_root_weight(pk, weight)
|
|
||||||
.map_err(|e| InternalStorageError(e.into()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get trust by public key
|
/// Get trust by public key
|
||||||
pub fn get(&self, pk: PublicKey) -> Result<Option<TrustNode>, TrustGraphError> {
|
pub fn get(&self, pk: PublicKey) -> Result<Option<TrustNode>, TrustGraphError> {
|
||||||
self.storage
|
Ok(self.storage.get(&pk.into())?)
|
||||||
.get(&pk.into())
|
|
||||||
.map_err(|e| InternalStorageError(e.into()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove cur_time from api, leave it for tests only
|
// TODO: remove cur_time from api, leave it for tests only
|
||||||
@ -112,8 +117,7 @@ where
|
|||||||
{
|
{
|
||||||
let roots: Vec<PublicKey> = self
|
let roots: Vec<PublicKey> = self
|
||||||
.storage
|
.storage
|
||||||
.root_keys()
|
.root_keys()?
|
||||||
.map_err(|e| InternalStorageError(e.into()))?
|
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
@ -122,28 +126,18 @@ where
|
|||||||
Certificate::verify(cert.borrow(), roots.as_slice(), cur_time)?;
|
Certificate::verify(cert.borrow(), roots.as_slice(), cur_time)?;
|
||||||
|
|
||||||
let mut chain = cert.borrow().chain.iter();
|
let mut chain = cert.borrow().chain.iter();
|
||||||
let root_trust = chain
|
let root_trust = chain.next().ok_or(EmptyChain)?;
|
||||||
.next()
|
|
||||||
.ok_or("empty chain")
|
|
||||||
.map_err(|e| InternalStorageError(e.into()))?;
|
|
||||||
let root_pk: PublicKeyHashable = root_trust.issued_for.clone().into();
|
let root_pk: PublicKeyHashable = root_trust.issued_for.clone().into();
|
||||||
|
|
||||||
// Insert new TrustNode for this root_pk if there wasn't one
|
// Insert new TrustNode for this root_pk if there wasn't one
|
||||||
if self
|
if self.storage.get(&root_pk)?.is_none() {
|
||||||
.storage
|
|
||||||
.get(&root_pk)
|
|
||||||
.map_err(|e| InternalStorageError(e.into()))?
|
|
||||||
.is_none()
|
|
||||||
{
|
|
||||||
let mut trust_node = TrustNode::new(root_trust.issued_for.clone(), cur_time);
|
let mut trust_node = TrustNode::new(root_trust.issued_for.clone(), cur_time);
|
||||||
let root_auth = Auth {
|
let root_auth = Auth {
|
||||||
trust: root_trust.clone(),
|
trust: root_trust.clone(),
|
||||||
issued_by: root_trust.issued_for.clone(),
|
issued_by: root_trust.issued_for.clone(),
|
||||||
};
|
};
|
||||||
trust_node.update_auth(root_auth);
|
trust_node.update_auth(root_auth);
|
||||||
self.storage
|
self.storage.insert(root_pk, trust_node)?;
|
||||||
.insert(root_pk, trust_node)
|
|
||||||
.map_err(|e| InternalStorageError(e.into()))?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert remaining trusts to the graph
|
// Insert remaining trusts to the graph
|
||||||
@ -157,8 +151,7 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.storage
|
self.storage
|
||||||
.update_auth(&pk, auth, &root_trust.issued_for, cur_time)
|
.update_auth(&pk, auth, &root_trust.issued_for, cur_time)?;
|
||||||
.map_err(|e| InternalStorageError(e.into()))?;
|
|
||||||
|
|
||||||
previous_trust = trust;
|
previous_trust = trust;
|
||||||
}
|
}
|
||||||
@ -171,18 +164,13 @@ where
|
|||||||
where
|
where
|
||||||
P: Borrow<PublicKey>,
|
P: Borrow<PublicKey>,
|
||||||
{
|
{
|
||||||
if let Some(weight) = self
|
if let Some(weight) = self.storage.get_root_weight(pk.borrow().as_ref())? {
|
||||||
.storage
|
|
||||||
.get_root_weight(pk.borrow().as_ref())
|
|
||||||
.map_err(|e| InternalStorageError(e.into()))?
|
|
||||||
{
|
|
||||||
return Ok(Some(weight));
|
return Ok(Some(weight));
|
||||||
}
|
}
|
||||||
|
|
||||||
let roots: Vec<PublicKey> = self
|
let roots: Vec<PublicKey> = self
|
||||||
.storage
|
.storage
|
||||||
.root_keys()
|
.root_keys()?
|
||||||
.map_err(|e| InternalStorageError(e.into()))?
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|pk| pk.clone().into())
|
.map(|pk| pk.clone().into())
|
||||||
.collect();
|
.collect();
|
||||||
@ -220,9 +208,7 @@ where
|
|||||||
|
|
||||||
let root_weight = self
|
let root_weight = self
|
||||||
.storage
|
.storage
|
||||||
.get_root_weight(first.issued_for.as_ref())
|
.get_root_weight(first.issued_for.as_ref())?
|
||||||
// This panic shouldn't happen // TODO: why?
|
|
||||||
.map_err(|e| InternalStorageError(e.into()))?
|
|
||||||
.ok_or(NoRoot)?;
|
.ok_or(NoRoot)?;
|
||||||
|
|
||||||
// certificate weight = root weight + 1 * every other element in the chain
|
// certificate weight = root weight + 1 * every other element in the chain
|
||||||
@ -264,12 +250,8 @@ where
|
|||||||
|
|
||||||
let auths: Vec<Auth> = self
|
let auths: Vec<Auth> = self
|
||||||
.storage
|
.storage
|
||||||
.get(&last.issued_by.clone().into())
|
.get(&last.issued_by.clone().into())?
|
||||||
.map_err(|e| InternalStorageError(e.into()))?
|
.ok_or(CertificateCheckError(Unexpected))?
|
||||||
.ok_or(CertificateCheckError(Unexpected(
|
|
||||||
"there cannot be paths without any nodes after adding verified certificates"
|
|
||||||
.to_string(),
|
|
||||||
)))?
|
|
||||||
.authorizations()
|
.authorizations()
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
@ -314,16 +296,10 @@ where
|
|||||||
P: Borrow<PublicKey>,
|
P: Borrow<PublicKey>,
|
||||||
{
|
{
|
||||||
// get all auths (edges) for issued public key
|
// get all auths (edges) for issued public key
|
||||||
let issued_for_node = self
|
let issued_for_node = self.storage.get(issued_for.borrow().as_ref())?;
|
||||||
.storage
|
|
||||||
.get(issued_for.borrow().as_ref())
|
|
||||||
.map_err(|e| InternalStorageError(e.into()))?;
|
|
||||||
|
|
||||||
let roots = roots.iter().map(|pk| pk.as_ref());
|
let roots = roots.iter().map(|pk| pk.as_ref());
|
||||||
let keys = self
|
let keys = self.storage.root_keys()?;
|
||||||
.storage
|
|
||||||
.root_keys()
|
|
||||||
.map_err(|e| InternalStorageError(e.into()))?;
|
|
||||||
let roots = keys.iter().chain(roots).collect();
|
let roots = keys.iter().chain(roots).collect();
|
||||||
|
|
||||||
match issued_for_node {
|
match issued_for_node {
|
||||||
@ -356,9 +332,7 @@ where
|
|||||||
|
|
||||||
let pk: PublicKeyHashable = revoke.pk.clone().into();
|
let pk: PublicKeyHashable = revoke.pk.clone().into();
|
||||||
|
|
||||||
self.storage
|
Ok(self.storage.revoke(&pk, revoke)?)
|
||||||
.revoke(&pk, revoke)
|
|
||||||
.map_err(|e| InternalStorageError(e.into()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check information about new certificates and about revoked certificates.
|
/// Check information about new certificates and about revoked certificates.
|
||||||
|
@ -1,29 +1,29 @@
|
|||||||
use crate::public_key_hashable::PublicKeyHashable;
|
use crate::public_key_hashable::PublicKeyHashable as PK;
|
||||||
use crate::revoke::Revoke;
|
use crate::revoke::Revoke;
|
||||||
use crate::trust_graph::Weight;
|
use crate::trust_graph::Weight;
|
||||||
use crate::trust_graph_storage::InMemoryStorageError::RevokeError;
|
use crate::trust_graph_storage::InMemoryStorageError::RevokeError;
|
||||||
use crate::trust_node::{Auth, TrustNode};
|
use crate::trust_node::{Auth, TrustNode};
|
||||||
use fluence_identity::public_key::PublicKey;
|
use fluence_identity::public_key::PublicKey;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::fmt::Display;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use thiserror::Error as ThisError;
|
use thiserror::Error as ThisError;
|
||||||
|
|
||||||
pub trait StorageError: std::error::Error {}
|
pub trait StorageError: std::error::Error + Display {}
|
||||||
|
|
||||||
pub trait Storage {
|
pub trait Storage {
|
||||||
type Error: StorageError + Into<String>;
|
type Error: StorageError + 'static;
|
||||||
|
|
||||||
fn get(&self, pk: &PublicKeyHashable) -> Result<Option<TrustNode>, Self::Error>;
|
fn get(&self, pk: &PK) -> Result<Option<TrustNode>, Self::Error>;
|
||||||
fn insert(&mut self, pk: PublicKeyHashable, node: TrustNode) -> Result<(), Self::Error>;
|
fn insert(&mut self, pk: PK, node: TrustNode) -> Result<(), Self::Error>;
|
||||||
|
|
||||||
fn get_root_weight(&self, pk: &PublicKeyHashable) -> Result<Option<Weight>, Self::Error>;
|
fn get_root_weight(&self, pk: &PK) -> Result<Option<Weight>, Self::Error>;
|
||||||
fn add_root_weight(&mut self, pk: PublicKeyHashable, weight: Weight)
|
fn add_root_weight(&mut self, pk: PK, weight: Weight) -> Result<(), Self::Error>;
|
||||||
-> Result<(), Self::Error>;
|
fn root_keys(&self) -> Result<Vec<PK>, Self::Error>;
|
||||||
fn root_keys(&self) -> Result<Vec<PublicKeyHashable>, Self::Error>;
|
fn revoke(&mut self, pk: &PK, revoke: Revoke) -> Result<(), Self::Error>;
|
||||||
fn revoke(&mut self, pk: &PublicKeyHashable, revoke: Revoke) -> Result<(), Self::Error>;
|
|
||||||
fn update_auth(
|
fn update_auth(
|
||||||
&mut self,
|
&mut self,
|
||||||
pk: &PublicKeyHashable,
|
pk: &PK,
|
||||||
auth: Auth,
|
auth: Auth,
|
||||||
issued_for: &PublicKey,
|
issued_for: &PublicKey,
|
||||||
cur_time: Duration,
|
cur_time: Duration,
|
||||||
@ -32,8 +32,8 @@ pub trait Storage {
|
|||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct InMemoryStorage {
|
pub struct InMemoryStorage {
|
||||||
nodes: HashMap<PublicKeyHashable, TrustNode>,
|
nodes: HashMap<PK, TrustNode>,
|
||||||
root_weights: HashMap<PublicKeyHashable, Weight>,
|
root_weights: HashMap<PK, Weight>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InMemoryStorage {
|
impl InMemoryStorage {
|
||||||
@ -64,44 +64,34 @@ pub enum InMemoryStorageError {
|
|||||||
RevokeError(String),
|
RevokeError(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<InMemoryStorageError> for String {
|
|
||||||
fn from(err: InMemoryStorageError) -> Self {
|
|
||||||
err.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StorageError for InMemoryStorageError {}
|
impl StorageError for InMemoryStorageError {}
|
||||||
|
|
||||||
impl Storage for InMemoryStorage {
|
impl Storage for InMemoryStorage {
|
||||||
type Error = InMemoryStorageError;
|
type Error = InMemoryStorageError;
|
||||||
|
|
||||||
fn get(&self, pk: &PublicKeyHashable) -> Result<Option<TrustNode>, Self::Error> {
|
fn get(&self, pk: &PK) -> Result<Option<TrustNode>, Self::Error> {
|
||||||
Ok(self.nodes.get(pk).cloned())
|
Ok(self.nodes.get(pk).cloned())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert(&mut self, pk: PublicKeyHashable, node: TrustNode) -> Result<(), Self::Error> {
|
fn insert(&mut self, pk: PK, node: TrustNode) -> Result<(), Self::Error> {
|
||||||
&self.nodes.insert(pk, node);
|
&self.nodes.insert(pk, node);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_root_weight(&self, pk: &PublicKeyHashable) -> Result<Option<Weight>, Self::Error> {
|
fn get_root_weight(&self, pk: &PK) -> Result<Option<Weight>, Self::Error> {
|
||||||
Ok(self.root_weights.get(pk).cloned())
|
Ok(self.root_weights.get(pk).cloned())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_root_weight(
|
fn add_root_weight(&mut self, pk: PK, weight: Weight) -> Result<(), Self::Error> {
|
||||||
&mut self,
|
|
||||||
pk: PublicKeyHashable,
|
|
||||||
weight: Weight,
|
|
||||||
) -> Result<(), Self::Error> {
|
|
||||||
&self.root_weights.insert(pk, weight);
|
&self.root_weights.insert(pk, weight);
|
||||||
Ok({})
|
Ok({})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn root_keys(&self) -> Result<Vec<PublicKeyHashable>, Self::Error> {
|
fn root_keys(&self) -> Result<Vec<PK>, Self::Error> {
|
||||||
Ok(self.root_weights.keys().cloned().map(Into::into).collect())
|
Ok(self.root_weights.keys().cloned().map(Into::into).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn revoke(&mut self, pk: &PublicKeyHashable, revoke: Revoke) -> Result<(), Self::Error> {
|
fn revoke(&mut self, pk: &PK, revoke: Revoke) -> Result<(), Self::Error> {
|
||||||
match self.nodes.get_mut(&pk) {
|
match self.nodes.get_mut(&pk) {
|
||||||
Some(trust_node) => {
|
Some(trust_node) => {
|
||||||
trust_node.update_revoke(revoke);
|
trust_node.update_revoke(revoke);
|
||||||
@ -115,7 +105,7 @@ impl Storage for InMemoryStorage {
|
|||||||
|
|
||||||
fn update_auth(
|
fn update_auth(
|
||||||
&mut self,
|
&mut self,
|
||||||
pk: &PublicKeyHashable,
|
pk: &PK,
|
||||||
auth: Auth,
|
auth: Auth,
|
||||||
issued_for: &PublicKey,
|
issued_for: &PublicKey,
|
||||||
cur_time: Duration,
|
cur_time: Duration,
|
||||||
|
0
bin/Cargo.lock → wasm/Cargo.lock
generated
0
bin/Cargo.lock → wasm/Cargo.lock
generated
@ -1,14 +1,13 @@
|
|||||||
use fluence::fce;
|
use fluence::fce;
|
||||||
use trust_graph::{Certificate as TGCertificate, Trust as TGTrust};
|
|
||||||
|
|
||||||
#[fce]
|
#[fce]
|
||||||
pub struct Certificate {
|
pub struct Certificate {
|
||||||
pub chain: Vec<Trust>,
|
pub chain: Vec<Trust>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TGCertificate> for Certificate {
|
impl From<trust_graph::Certificate> for Certificate {
|
||||||
fn from(t: TGCertificate) -> Self {
|
fn from(c: trust_graph::Certificate) -> Self {
|
||||||
let chain: Vec<Trust> = t.chain.into_iter().map(|t| t.into()).collect();
|
let chain: Vec<Trust> = c.chain.into_iter().map(|t| t.into()).collect();
|
||||||
return Certificate { chain };
|
return Certificate { chain };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -26,8 +25,8 @@ pub struct Trust {
|
|||||||
pub issued_at: u64,
|
pub issued_at: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TGTrust> for Trust {
|
impl From<trust_graph::Trust> for Trust {
|
||||||
fn from(t: TGTrust) -> Self {
|
fn from(t: trust_graph::Trust) -> Self {
|
||||||
let issued_for = bs58::encode(t.issued_for.to_bytes()).into_string();
|
let issued_for = bs58::encode(t.issued_for.to_bytes()).into_string();
|
||||||
let signature = bs58::encode(t.signature.to_bytes()).into_string();
|
let signature = bs58::encode(t.signature.to_bytes()).into_string();
|
||||||
let expires_at = t.expires_at.as_secs();
|
let expires_at = t.expires_at.as_secs();
|
@ -1,6 +1,6 @@
|
|||||||
use fluence::WasmLoggerBuilder;
|
use fluence::WasmLoggerBuilder;
|
||||||
|
|
||||||
mod proxy_structs;
|
mod dto;
|
||||||
mod results;
|
mod results;
|
||||||
mod service_api;
|
mod service_api;
|
||||||
mod storage_impl;
|
mod storage_impl;
|
@ -1,4 +1,4 @@
|
|||||||
use crate::proxy_structs::Certificate;
|
use crate::dto::Certificate;
|
||||||
use fluence::fce;
|
use fluence::fce;
|
||||||
|
|
||||||
#[fce]
|
#[fce]
|
@ -1,17 +1,16 @@
|
|||||||
use crate::proxy_structs::Certificate;
|
use crate::dto::Certificate;
|
||||||
use crate::results::{AllCertsResult, InsertResult, WeightResult};
|
use crate::results::{AllCertsResult, InsertResult, WeightResult};
|
||||||
use crate::storage_impl::get_data;
|
use crate::storage_impl::get_data;
|
||||||
use fluence::fce;
|
use fluence::fce;
|
||||||
use fluence_identity::{KeyPair, PublicKey};
|
use fluence_identity::{KeyPair, PublicKey};
|
||||||
use std::convert::{From, Into};
|
use std::convert::Into;
|
||||||
use std::fmt::Display;
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use trust_graph::Certificate as TGCertificate;
|
|
||||||
|
|
||||||
fn insert_cert_impl(certificate: String, duration: u64) -> Result<(), String> {
|
fn insert_cert_impl(certificate: String, duration: u64) -> Result<(), String> {
|
||||||
let duration = Duration::from_millis(duration);
|
let duration = Duration::from_millis(duration);
|
||||||
let certificate = TGCertificate::from_str(&certificate)?;
|
let certificate =
|
||||||
|
trust_graph::Certificate::from_str(&certificate).map_err(|e| format!("{}", e))?;
|
||||||
|
|
||||||
let mut tg = get_data().lock();
|
let mut tg = get_data().lock();
|
||||||
tg.add(certificate, duration)?;
|
tg.add(certificate, duration)?;
|
||||||
@ -25,7 +24,7 @@ fn insert_cert(certificate: String, duration: u64) -> InsertResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_weight_impl(public_key: String) -> Result<Option<u32>, String> {
|
fn get_weight_impl(public_key: String) -> Result<Option<u32>, String> {
|
||||||
let mut tg = get_data().lock();
|
let tg = get_data().lock();
|
||||||
|
|
||||||
let public_key = string_to_public_key(public_key)?;
|
let public_key = string_to_public_key(public_key)?;
|
||||||
|
|
||||||
@ -49,12 +48,13 @@ fn string_to_public_key(public_key: String) -> Result<PublicKey, String> {
|
|||||||
Ok(public_key)
|
Ok(public_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[fce]
|
||||||
fn get_all_certs(issued_for: String) -> AllCertsResult {
|
fn get_all_certs(issued_for: String) -> AllCertsResult {
|
||||||
get_all_certs_impl(issued_for).into()
|
get_all_certs_impl(issued_for).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_all_certs_impl(issued_for: String) -> Result<Vec<Certificate>, String> {
|
fn get_all_certs_impl(issued_for: String) -> Result<Vec<Certificate>, String> {
|
||||||
let mut tg = get_data().lock();
|
let tg = get_data().lock();
|
||||||
|
|
||||||
let public_key = string_to_public_key(issued_for)?;
|
let public_key = string_to_public_key(issued_for)?;
|
||||||
let certs = tg.get_all_certs(public_key, &[])?;
|
let certs = tg.get_all_certs(public_key, &[])?;
|
||||||
@ -72,7 +72,12 @@ fn test() -> String {
|
|||||||
let expires_at = Duration::new(15, 15);
|
let expires_at = Duration::new(15, 15);
|
||||||
let issued_at = Duration::new(5, 5);
|
let issued_at = Duration::new(5, 5);
|
||||||
|
|
||||||
let cert = TGCertificate::issue_root(&root_kp, second_kp.public_key(), expires_at, issued_at);
|
let cert = trust_graph::Certificate::issue_root(
|
||||||
|
&root_kp,
|
||||||
|
second_kp.public_key(),
|
||||||
|
expires_at,
|
||||||
|
issued_at,
|
||||||
|
);
|
||||||
tg.add_root_weight(root_kp.public().into(), 0).unwrap();
|
tg.add_root_weight(root_kp.public().into(), 0).unwrap();
|
||||||
tg.add_root_weight(root_kp2.public().into(), 1).unwrap();
|
tg.add_root_weight(root_kp2.public().into(), 1).unwrap();
|
||||||
tg.add(cert, Duration::new(10, 10)).unwrap();
|
tg.add(cert, Duration::new(10, 10)).unwrap();
|
@ -2,8 +2,9 @@
|
|||||||
// check if trust is already in list before adding
|
// check if trust is already in list before adding
|
||||||
// if there is an older trust - don't add received trust
|
// if there is an older trust - don't add received trust
|
||||||
|
|
||||||
use crate::storage_impl::SqliteStorageError::{
|
use crate::storage_impl::SQLiteStorageError::{
|
||||||
ConvertionError, DecodeError, EncodeError, RevokeError, SqliteError, Unexpected,
|
DecodeError, EncodeError, PublcKeyNotFound, PublicKeyConversion, PublicKeyFromStr, SQLiteError,
|
||||||
|
TrustNodeConversion, WeightConversionDB,
|
||||||
};
|
};
|
||||||
use core::convert::TryFrom;
|
use core::convert::TryFrom;
|
||||||
use fce_sqlite_connector;
|
use fce_sqlite_connector;
|
||||||
@ -23,9 +24,9 @@ use trust_graph::{
|
|||||||
Auth, PublicKeyHashable, Revoke, Storage, StorageError, TrustGraph, TrustNode, Weight,
|
Auth, PublicKeyHashable, Revoke, Storage, StorageError, TrustGraph, TrustNode, Weight,
|
||||||
};
|
};
|
||||||
|
|
||||||
static INSTANCE: OnceCell<Mutex<TrustGraph<SqliteStorage>>> = OnceCell::new();
|
static INSTANCE: OnceCell<Mutex<TrustGraph<SQLiteStorage>>> = OnceCell::new();
|
||||||
|
|
||||||
pub fn get_data() -> &'static Mutex<TrustGraph<SqliteStorage>> {
|
pub fn get_data() -> &'static Mutex<TrustGraph<SQLiteStorage>> {
|
||||||
INSTANCE.get_or_init(|| {
|
INSTANCE.get_or_init(|| {
|
||||||
let db_path = "/tmp/users123123.sqlite";
|
let db_path = "/tmp/users123123.sqlite";
|
||||||
let connection = fce_sqlite_connector::open(db_path).unwrap();
|
let connection = fce_sqlite_connector::open(db_path).unwrap();
|
||||||
@ -41,64 +42,68 @@ pub fn get_data() -> &'static Mutex<TrustGraph<SqliteStorage>> {
|
|||||||
|
|
||||||
connection.execute(init_sql).expect("cannot connect to db");
|
connection.execute(init_sql).expect("cannot connect to db");
|
||||||
|
|
||||||
Mutex::new(TrustGraph::new(Box::new(SqliteStorage::new(connection))))
|
Mutex::new(TrustGraph::new(Box::new(SQLiteStorage::new(connection))))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SqliteStorage {
|
pub struct SQLiteStorage {
|
||||||
connection: Connection,
|
connection: Connection,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SqliteStorage {
|
impl SQLiteStorage {
|
||||||
pub fn new(connection: Connection) -> SqliteStorage {
|
pub fn new(connection: Connection) -> SQLiteStorage {
|
||||||
SqliteStorage { connection }
|
SQLiteStorage { connection }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(ThisError, Debug)]
|
#[derive(ThisError, Debug)]
|
||||||
pub enum SqliteStorageError {
|
pub enum SQLiteStorageError {
|
||||||
#[error("Unexpected: {0}")]
|
|
||||||
Unexpected(String),
|
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
SqliteError(InternalSqliteError),
|
SQLiteError(InternalSqliteError),
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
EncodeError(String),
|
PublicKeyFromStr(String),
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
DecodeError(String),
|
EncodeError(RmpEncodeError),
|
||||||
#[error("There is no entry for {0}")]
|
#[error("{0}")]
|
||||||
ConvertionError(String),
|
DecodeError(RmpDecodeError),
|
||||||
#[error("Cannot revoke a trust: {0}")]
|
#[error("Cannot convert weight as integer from DB")]
|
||||||
RevokeError(String),
|
WeightConversionDB,
|
||||||
|
#[error("Cannot convert public key as binary from DB")]
|
||||||
|
PublicKeyConversion,
|
||||||
|
#[error("Cannot convert trust node as binary from DB")]
|
||||||
|
TrustNodeConversion,
|
||||||
|
#[error("Cannot revoke. There is no trust with such PublicKey")]
|
||||||
|
PublcKeyNotFound,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<InternalSqliteError> for SqliteStorageError {
|
impl From<InternalSqliteError> for SQLiteStorageError {
|
||||||
fn from(err: InternalSqliteError) -> Self {
|
fn from(err: InternalSqliteError) -> Self {
|
||||||
SqliteError(err)
|
SQLiteError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RmpEncodeError> for SqliteStorageError {
|
impl From<RmpEncodeError> for SQLiteStorageError {
|
||||||
fn from(err: RmpEncodeError) -> Self {
|
fn from(err: RmpEncodeError) -> Self {
|
||||||
EncodeError(format!("{}", err))
|
EncodeError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RmpDecodeError> for SqliteStorageError {
|
impl From<RmpDecodeError> for SQLiteStorageError {
|
||||||
fn from(err: RmpDecodeError) -> Self {
|
fn from(err: RmpDecodeError) -> Self {
|
||||||
DecodeError(format!("{}", err))
|
DecodeError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SqliteStorageError> for String {
|
impl From<SQLiteStorageError> for String {
|
||||||
fn from(err: SqliteStorageError) -> Self {
|
fn from(err: SQLiteStorageError) -> Self {
|
||||||
err.into()
|
err.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StorageError for SqliteStorageError {}
|
impl StorageError for SQLiteStorageError {}
|
||||||
|
|
||||||
impl Storage for SqliteStorage {
|
impl Storage for SQLiteStorage {
|
||||||
type Error = SqliteStorageError;
|
type Error = SQLiteStorageError;
|
||||||
|
|
||||||
fn get(&self, pk: &PublicKeyHashable) -> Result<Option<TrustNode>, Self::Error> {
|
fn get(&self, pk: &PublicKeyHashable) -> Result<Option<TrustNode>, Self::Error> {
|
||||||
let mut cursor = self
|
let mut cursor = self
|
||||||
@ -111,9 +116,7 @@ impl Storage for SqliteStorage {
|
|||||||
match cursor.next().unwrap() {
|
match cursor.next().unwrap() {
|
||||||
Some(r) => {
|
Some(r) => {
|
||||||
log::info!("row: {:?}", r);
|
log::info!("row: {:?}", r);
|
||||||
let tn_bin: &[u8] = r[0].as_binary().ok_or(ConvertionError(
|
let tn_bin: &[u8] = r[0].as_binary().ok_or(TrustNodeConversion)?;
|
||||||
"cannot get trustnode as binary".to_string(),
|
|
||||||
))?;
|
|
||||||
|
|
||||||
log::info!("binary: {:?}", tn_bin);
|
log::info!("binary: {:?}", tn_bin);
|
||||||
|
|
||||||
@ -155,12 +158,8 @@ impl Storage for SqliteStorage {
|
|||||||
if let Some(row) = cursor.next()? {
|
if let Some(row) = cursor.next()? {
|
||||||
log::info!("row: {:?}", row);
|
log::info!("row: {:?}", row);
|
||||||
|
|
||||||
let w = u32::try_from(
|
let w = u32::try_from(row[1].as_integer().ok_or(WeightConversionDB)?)
|
||||||
row[1]
|
.map_err(|_e| WeightConversionDB)?;
|
||||||
.as_integer()
|
|
||||||
.ok_or(ConvertionError("cannot get weight as integer".to_string()))?,
|
|
||||||
)
|
|
||||||
.map_err(|e| Unexpected(format!("Unexpected. Cannot convert weight to u32: {}", e)))?;
|
|
||||||
|
|
||||||
Ok(Some(w))
|
Ok(Some(w))
|
||||||
} else {
|
} else {
|
||||||
@ -198,11 +197,9 @@ impl Storage for SqliteStorage {
|
|||||||
|
|
||||||
while let Some(row) = cursor.next()? {
|
while let Some(row) = cursor.next()? {
|
||||||
log::info!("row: {:?}", row);
|
log::info!("row: {:?}", row);
|
||||||
let pk = row[0].as_string().ok_or(ConvertionError(
|
let pk = row[0].as_string().ok_or(PublicKeyConversion)?;
|
||||||
"cannot get public key as binary".to_string(),
|
|
||||||
))?;
|
|
||||||
let pk: PublicKeyHashable =
|
let pk: PublicKeyHashable =
|
||||||
PublicKeyHashable::from_str(pk).map_err(|e| DecodeError(e.to_string()))?;
|
PublicKeyHashable::from_str(pk).map_err(|e| PublicKeyFromStr(e.to_string()))?;
|
||||||
|
|
||||||
roots.push(pk)
|
roots.push(pk)
|
||||||
}
|
}
|
||||||
@ -217,9 +214,7 @@ impl Storage for SqliteStorage {
|
|||||||
self.insert(pk.clone(), trust_node)?;
|
self.insert(pk.clone(), trust_node)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
None => Err(RevokeError(
|
None => Err(PublcKeyNotFound),
|
||||||
"There is no trust with such PublicKey".to_string(),
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user