mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-25 08:07:57 +01:00
Make more things burn less
This commit is contained in:
parent
150b2e68d9
commit
3231b51f89
@ -27,7 +27,6 @@ pub use typed::{
|
|||||||
|
|
||||||
Adapter,
|
Adapter,
|
||||||
OutputBuffer,
|
OutputBuffer,
|
||||||
OutputWriter,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mod hash;
|
mod hash;
|
||||||
@ -112,7 +111,7 @@ impl<V: Serialize<Ser>> Adapter for AllocAdapter<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct AlignedAdapter<V> {
|
pub struct AlignedAdapter<V> {
|
||||||
phantom: PhantomData<V>,
|
phantom: PhantomData<V>,
|
||||||
}
|
}
|
||||||
@ -136,6 +135,7 @@ impl<V: Serialize<AlignedSerializer<AlignedVec>>> Adapter for AlignedAdapter<V>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Databases {
|
pub struct Databases {
|
||||||
pub userdb: UserDB,
|
pub userdb: UserDB,
|
||||||
pub passdb: PassDB,
|
pub passdb: PassDB,
|
||||||
|
@ -6,7 +6,10 @@ use std::{
|
|||||||
BuildHasher,
|
BuildHasher,
|
||||||
},
|
},
|
||||||
collections::hash_map::RandomState,
|
collections::hash_map::RandomState,
|
||||||
|
fmt,
|
||||||
|
fmt::Debug,
|
||||||
};
|
};
|
||||||
|
use std::fmt::Formatter;
|
||||||
|
|
||||||
use rkyv::{
|
use rkyv::{
|
||||||
Archive,
|
Archive,
|
||||||
@ -31,7 +34,7 @@ use super::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Archive, Serialize, Deserialize)]
|
#[derive(Archive, Serialize, Deserialize, Debug)]
|
||||||
/// The entry as it is stored inside the database.
|
/// The entry as it is stored inside the database.
|
||||||
pub struct Entry<K: Archive, V: Archive> {
|
pub struct Entry<K: Archive, V: Archive> {
|
||||||
pub key: K,
|
pub key: K,
|
||||||
@ -48,6 +51,12 @@ impl<K, A> HashAdapter<K, A> {
|
|||||||
Self { k: PhantomData, a: PhantomData }
|
Self { k: PhantomData, a: PhantomData }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<K, A> Debug for HashAdapter<K, A> {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
use core::any::type_name;
|
||||||
|
write!(f, "HashAdapter<{}, {}>", type_name::<K>(), type_name::<A>())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<K, A: Fallible> Fallible for HashAdapter<K, A> { type Error = <A as Fallible>::Error; }
|
impl<K, A: Fallible> Fallible for HashAdapter<K, A> { type Error = <A as Fallible>::Error; }
|
||||||
impl<K, A: Adapter> Adapter for HashAdapter<K, A>
|
impl<K, A: Adapter> Adapter for HashAdapter<K, A>
|
||||||
@ -77,6 +86,16 @@ pub struct HashDB<A, K, H = RandomState>
|
|||||||
hash_builder: H,
|
hash_builder: H,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<A: Adapter, K, H: Debug> fmt::Debug for HashDB<A, K, H> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
let adapter = HashAdapter::<A,K>::new();
|
||||||
|
f.debug_struct("HashDB")
|
||||||
|
.field("db", &adapter)
|
||||||
|
.field("hasher", &self.hash_builder)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<A, K> HashDB<A, K>
|
impl<A, K> HashDB<A, K>
|
||||||
{
|
{
|
||||||
pub unsafe fn create(env: &Environment, name: Option<&str>) -> lmdb::Result<Self> {
|
pub unsafe fn create(env: &Environment, name: Option<&str>) -> lmdb::Result<Self> {
|
||||||
|
@ -10,7 +10,7 @@ use super::Transaction;
|
|||||||
use argon2;
|
use argon2;
|
||||||
|
|
||||||
type Adapter = AllocAdapter<String>;
|
type Adapter = AllocAdapter<String>;
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PassDB {
|
pub struct PassDB {
|
||||||
env: Arc<Environment>,
|
env: Arc<Environment>,
|
||||||
db: DB<Adapter>,
|
db: DB<Adapter>,
|
||||||
|
@ -19,7 +19,7 @@ pub struct Resource {
|
|||||||
description_idx: u64,
|
description_idx: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ResourceDB {
|
pub struct ResourceDB {
|
||||||
env: Arc<Environment>,
|
env: Arc<Environment>,
|
||||||
db: DB<AllocAdapter<Resource>>,
|
db: DB<AllocAdapter<Resource>>,
|
||||||
|
@ -31,18 +31,28 @@ use lmdb::{
|
|||||||
|
|
||||||
use super::RawDB;
|
use super::RawDB;
|
||||||
|
|
||||||
|
/// Database Adapter to create a typed DB returning Rust types
|
||||||
pub trait Adapter: Fallible {
|
pub trait Adapter: Fallible {
|
||||||
|
/// The serializer that will be instantiated to resolve the stored types
|
||||||
type Serializer: rkyv::ser::Serializer;
|
type Serializer: rkyv::ser::Serializer;
|
||||||
|
/// Actual Value that will be extracted
|
||||||
type Value: Serialize<Self::Serializer>;
|
type Value: Serialize<Self::Serializer>;
|
||||||
|
|
||||||
|
/// Create a new serializer
|
||||||
fn new_serializer() -> Self::Serializer;
|
fn new_serializer() -> Self::Serializer;
|
||||||
|
|
||||||
|
/// Convert any Serializer Error in your shared error.
|
||||||
|
///
|
||||||
|
/// You *must* implement this if you don't use `Infallible` as Supertrait.
|
||||||
fn from_ser_err(e: <Self::Serializer as Fallible>::Error) -> <Self as Fallible>::Error;
|
fn from_ser_err(e: <Self::Serializer as Fallible>::Error) -> <Self as Fallible>::Error;
|
||||||
|
|
||||||
|
/// Convert the Database Error type into your shared error.
|
||||||
|
// TODO: Extract both conversion into their own trait because there's a sensible impl for
|
||||||
|
// `Infallible` for both.
|
||||||
fn from_db_err(e: lmdb::Error) -> <Self as Fallible>::Error;
|
fn from_db_err(e: lmdb::Error) -> <Self as Fallible>::Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AdapterPrettyPrinter<A: Adapter>(PhantomData<A>);
|
struct AdapterPrettyPrinter<A: Adapter>(PhantomData<A>);
|
||||||
|
|
||||||
impl<A: Adapter> AdapterPrettyPrinter<A> {
|
impl<A: Adapter> AdapterPrettyPrinter<A> {
|
||||||
pub fn new() -> Self { Self(PhantomData) }
|
pub fn new() -> Self { Self(PhantomData) }
|
||||||
}
|
}
|
||||||
@ -56,8 +66,11 @@ impl<A: Adapter> fmt::Debug for AdapterPrettyPrinter<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deserialize adapter to write into an Buffer
|
||||||
pub trait OutputBuffer {
|
pub trait OutputBuffer {
|
||||||
|
/// The kind of buffer
|
||||||
type Buffer: AsRef<[u8]>;
|
type Buffer: AsRef<[u8]>;
|
||||||
|
/// convert yourself into this buffer
|
||||||
fn into_slice(self) -> Self::Buffer;
|
fn into_slice(self) -> Self::Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,11 +81,6 @@ impl<const N: usize> OutputBuffer for AllocSerializer<N> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This should be possible to autoimplement for Sized Serializers
|
|
||||||
pub trait OutputWriter: Fallible {
|
|
||||||
fn write_into(&mut self, buf: &mut [u8]) -> Result<(), Self::Error>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DB<A> {
|
pub struct DB<A> {
|
||||||
db: RawDB,
|
db: RawDB,
|
||||||
phantom: PhantomData<A>,
|
phantom: PhantomData<A>,
|
||||||
@ -171,26 +179,7 @@ impl<'a, A> DB<A>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, A> DB<A>
|
#[derive(Debug)]
|
||||||
where A: Adapter,
|
|
||||||
A::Serializer: OutputWriter,
|
|
||||||
{
|
|
||||||
pub fn put_nocopy<K: AsRef<[u8]>>(&self, txn: &mut RwTransaction, key: &K, val: &A::Value, flags: WriteFlags)
|
|
||||||
-> Result<usize, A::Error>
|
|
||||||
{
|
|
||||||
let mut serializer = A::new_serializer();
|
|
||||||
let pos = serializer.serialize_value(val)
|
|
||||||
.map_err(A::from_ser_err)?;
|
|
||||||
|
|
||||||
let mut buf = self.db.reserve(txn, &key.as_ref(), pos, flags)
|
|
||||||
.map_err(A::from_db_err)?;
|
|
||||||
serializer.write_into(&mut buf)
|
|
||||||
.map_err(A::from_ser_err)?;
|
|
||||||
|
|
||||||
Ok(pos)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TypedCursor<C, A> {
|
pub struct TypedCursor<C, A> {
|
||||||
cursor: C,
|
cursor: C,
|
||||||
phantom: PhantomData<A>,
|
phantom: PhantomData<A>,
|
||||||
@ -218,6 +207,7 @@ impl<'txn, C, A> TypedCursor<C, A>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Iter<'txn, A> {
|
pub struct Iter<'txn, A> {
|
||||||
iter: lmdb::Iter<'txn>,
|
iter: lmdb::Iter<'txn>,
|
||||||
phantom: PhantomData<A>,
|
phantom: PhantomData<A>,
|
||||||
|
@ -6,7 +6,7 @@ use crate::db::{DatabaseFlags, LMDBorrow, RoTransaction, WriteFlags, };
|
|||||||
use rkyv::{Archive, Serialize, Deserialize, Archived};
|
use rkyv::{Archive, Serialize, Deserialize, Archived};
|
||||||
|
|
||||||
type Adapter = AllocAdapter<User>;
|
type Adapter = AllocAdapter<User>;
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct UserDB {
|
pub struct UserDB {
|
||||||
env: Arc<Environment>,
|
env: Arc<Environment>,
|
||||||
db: DB<Adapter>,
|
db: DB<Adapter>,
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use serde_dhall;
|
|
||||||
|
|
||||||
use rsasl::SaslError;
|
use rsasl::SaslError;
|
||||||
|
|
||||||
@ -9,8 +8,8 @@ use crate::db::DBError;
|
|||||||
//FIXME use crate::network;
|
//FIXME use crate::network;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
/// Shared error type
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
Dhall(serde_dhall::Error),
|
|
||||||
SASL(SaslError),
|
SASL(SaslError),
|
||||||
IO(io::Error),
|
IO(io::Error),
|
||||||
Boxed(Box<dyn std::error::Error>),
|
Boxed(Box<dyn std::error::Error>),
|
||||||
@ -22,9 +21,6 @@ pub enum Error {
|
|||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Error::Dhall(e) => {
|
|
||||||
write!(f, "Dhall coding error: {}", e)
|
|
||||||
},
|
|
||||||
Error::SASL(e) => {
|
Error::SASL(e) => {
|
||||||
write!(f, "SASL Error: {}", e)
|
write!(f, "SASL Error: {}", e)
|
||||||
},
|
},
|
||||||
@ -59,12 +55,6 @@ impl From<io::Error> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<serde_dhall::Error> for Error {
|
|
||||||
fn from(e: serde_dhall::Error) -> Error {
|
|
||||||
Error::Dhall(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Box<dyn std::error::Error>> for Error {
|
impl From<Box<dyn std::error::Error>> for Error {
|
||||||
fn from(e: Box<dyn std::error::Error>) -> Error {
|
fn from(e: Box<dyn std::error::Error>) -> Error {
|
||||||
Error::Boxed(e)
|
Error::Boxed(e)
|
||||||
@ -81,6 +71,4 @@ impl From<DBError> for Error {
|
|||||||
fn from(e: DBError) -> Error {
|
fn from(e: DBError) -> Error {
|
||||||
Error::DB(e)
|
Error::DB(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type Result<T> = std::result::Result<T, Error>;
|
|
16
bffhd/lib.rs
16
bffhd/lib.rs
@ -1,14 +1,26 @@
|
|||||||
#![forbid(unused_imports)]
|
#![forbid(unused_imports)]
|
||||||
#![warn(missing_docs, missing_debug_implementations)]
|
#![warn(missing_debug_implementations)]
|
||||||
|
|
||||||
|
//! Diflouroborane
|
||||||
|
//!
|
||||||
|
//! This is the server component of the FabAccess project.
|
||||||
|
//! The entry point of bffhd can be found in [bin/bffhd/main.rs](../bin/bffhd/main.rs)
|
||||||
|
//!
|
||||||
|
//! P.S.: If you're curious about the name; the project was initially called "Better Fablab
|
||||||
|
//! Friend and Helper" (BFFH). And the chemical formula of Diflouroborane is BF2H.
|
||||||
|
|
||||||
|
/// Internal Databases build on top of LMDB, a mmap()'ed B-tree DB optimized for reads
|
||||||
pub mod db;
|
pub mod db;
|
||||||
|
/// Shared error type
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod network;
|
|
||||||
pub mod oid;
|
pub mod oid;
|
||||||
|
/// Policy decision engine
|
||||||
pub mod permissions;
|
pub mod permissions;
|
||||||
|
/// Resources
|
||||||
pub mod resource;
|
pub mod resource;
|
||||||
|
/// State of Resources
|
||||||
pub mod state;
|
pub mod state;
|
||||||
|
/// Varints
|
||||||
pub mod varint;
|
pub mod varint;
|
||||||
|
|
||||||
use intmap::IntMap;
|
use intmap::IntMap;
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
use std::{
|
|
||||||
sync::Arc,
|
|
||||||
collections::HashMap,
|
|
||||||
};
|
|
||||||
|
|
||||||
use futures_signals::signal::{
|
|
||||||
Mutable,
|
|
||||||
MutableSignalCloned
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::state::State;
|
|
||||||
|
|
||||||
type ResourceState = Mutable<Arc<State>>;
|
|
||||||
type ResourceStateSignal = MutableSignalCloned<Arc<State>>;
|
|
||||||
|
|
||||||
/// Connection Broker between Resources and Subscribers
|
|
||||||
///
|
|
||||||
/// This serves as touch-off point between resources and anybody else. It doesn't drive
|
|
||||||
/// any state updates, it only allows subscribers to subscribe to the resources that are
|
|
||||||
/// driving the state updates
|
|
||||||
pub struct Network {
|
|
||||||
sources: HashMap<u64, ResourceState>,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
44
bffhd/oid.rs
44
bffhd/oid.rs
@ -293,23 +293,6 @@ fn parse_string_first_node(first_child_node: &str) -> Result<u8, ObjectIdentifie
|
|||||||
Ok(first_child_node)
|
Ok(first_child_node)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_string_child_node(
|
|
||||||
node_str: &str,
|
|
||||||
out: &mut Vec<u8>
|
|
||||||
) -> Result<(), ObjectIdentifierError> {
|
|
||||||
let node: Node = node_str.parse()
|
|
||||||
.map_err(|_| ObjectIdentifierError::IllegalChildNodeValue)?;
|
|
||||||
// TODO bench against !*node &= 0x80, compiler may already optimize better
|
|
||||||
if node <= 127 {
|
|
||||||
out.push(node as u8);
|
|
||||||
} else {
|
|
||||||
let vi: VarNode = node.into();
|
|
||||||
out.extend_from_slice(vi.as_bytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ObjectIdentifier {
|
impl ObjectIdentifier {
|
||||||
fn from_string<S>(value: S) -> Result<ObjectIdentifier, ObjectIdentifierError>
|
fn from_string<S>(value: S) -> Result<ObjectIdentifier, ObjectIdentifierError>
|
||||||
where
|
where
|
||||||
@ -512,7 +495,7 @@ pub(crate) mod tests {
|
|||||||
pub(crate) fn gen_random() -> ObjectIdentifier {
|
pub(crate) fn gen_random() -> ObjectIdentifier {
|
||||||
let amt: u8 = rand::random::<u8>() % 10 + 1;
|
let amt: u8 = rand::random::<u8>() % 10 + 1;
|
||||||
let mut children = Vec::new();
|
let mut children = Vec::new();
|
||||||
for i in 0..amt {
|
for _ in 0..amt {
|
||||||
children.push(rand::random());
|
children.push(rand::random());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -868,6 +851,31 @@ pub(crate) mod tests {
|
|||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_string_large_children_ok() {
|
||||||
|
let expected =
|
||||||
|
ObjectIdentifier::build(ObjectIdentifierRoot::JointIsoItuT,
|
||||||
|
25,
|
||||||
|
vec![190754093376743485973207716749546715206,
|
||||||
|
255822649272987943607843257596365752308,
|
||||||
|
15843412533224453995377625663329542022,
|
||||||
|
6457999595881951503805148772927347934,
|
||||||
|
19545192863105095042881850060069531734,
|
||||||
|
195548685662657784196186957311035194990,
|
||||||
|
233020488258340943072303499291936117654,
|
||||||
|
193307160423854019916786016773068715190,
|
||||||
|
]).unwrap();
|
||||||
|
let actual = "2.25.190754093376743485973207716749546715206.\
|
||||||
|
255822649272987943607843257596365752308.\
|
||||||
|
15843412533224453995377625663329542022.\
|
||||||
|
6457999595881951503805148772927347934.\
|
||||||
|
19545192863105095042881850060069531734.\
|
||||||
|
195548685662657784196186957311035194990.\
|
||||||
|
233020488258340943072303499291936117654.\
|
||||||
|
193307160423854019916786016773068715190".try_into().unwrap();
|
||||||
|
assert_eq!(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn encode_to_string() {
|
fn encode_to_string() {
|
||||||
let expected = String::from("1.2.3.4");
|
let expected = String::from("1.2.3.4");
|
||||||
|
@ -64,6 +64,7 @@ pub enum Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: more message context
|
// TODO: more message context
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Update {
|
pub struct Update {
|
||||||
pub state: State,
|
pub state: State,
|
||||||
pub errchan: Sender<Error>,
|
pub errchan: Sender<Error>,
|
||||||
|
@ -73,6 +73,7 @@ impl fmt::Debug for State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct StateBuilder {
|
pub struct StateBuilder {
|
||||||
hasher: DefaultHasher,
|
hasher: DefaultHasher,
|
||||||
inner: Vec<OwnedEntry>
|
inner: Vec<OwnedEntry>
|
||||||
|
@ -380,6 +380,7 @@ impl ImplData<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct ImplEntry<'a> {
|
pub struct ImplEntry<'a> {
|
||||||
id: ImplId<'a>,
|
id: ImplId<'a>,
|
||||||
data: ImplData<'a>,
|
data: ImplData<'a>,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::ops::{Deref};
|
use std::ops::{Deref};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct VarUInt<const N: usize> {
|
pub struct VarUInt<const N: usize> {
|
||||||
offset: usize,
|
offset: usize,
|
||||||
bytes: [u8; N],
|
bytes: [u8; N],
|
||||||
|
@ -75,7 +75,8 @@ fn main() -> Result<(), Error> {
|
|||||||
|
|
||||||
// If no `config` option is given use a preset default.
|
// If no `config` option is given use a preset default.
|
||||||
let configpath = matches.value_of("config").unwrap_or("/etc/diflouroborane.dhall");
|
let configpath = matches.value_of("config").unwrap_or("/etc/diflouroborane.dhall");
|
||||||
let config = config::read(&PathBuf::from_str(configpath).unwrap())?;
|
let config = config::read(&PathBuf::from_str(configpath).unwrap())
|
||||||
|
.expect("Failed to parse config");
|
||||||
println!("{:#?}", config);
|
println!("{:#?}", config);
|
||||||
|
|
||||||
let mut sockaddrs = Vec::new();
|
let mut sockaddrs = Vec::new();
|
||||||
|
Loading…
Reference in New Issue
Block a user