Skip to content

Commit

Permalink
refactor(rust): move the lmdb storage
Browse files Browse the repository at this point in the history
to be able to compile rust doc examples to build a node
  • Loading branch information
etorreborre committed Apr 18, 2023
1 parent 1f80fff commit 7f21117
Show file tree
Hide file tree
Showing 15 changed files with 152 additions and 101 deletions.
6 changes: 5 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions implementations/rust/ockam/ockam/src/lib.rs
Expand Up @@ -57,6 +57,8 @@ pub mod workers;
#[cfg(feature = "std")]
pub use ockam_abac as abac;
pub use ockam_identity as identity;
#[cfg(feature = "std")]
pub use ockam_identity::storage::lmdb_storage::*;

pub use ockam_core::{
allow, deny, errcode, route, Address, Any, AsyncTryClone, Encoded, Error, LocalMessage,
Expand Down
8 changes: 4 additions & 4 deletions implementations/rust/ockam/ockam/src/node.rs
Expand Up @@ -43,15 +43,15 @@ pub struct Node {
///
/// ```
/// Here is another example where we specify a local LMDB database to store identity attributes
/// ```
/// ```rust
/// use std::sync::Arc;
/// use ockam::{Node, Result};
/// use ockam::LmdbStorage;
/// use ockam_node::Context;
/// use ockam_vault::storage::FileStorage;
/// use ockam_api::lmdb::LmdbStorage;
///
/// async fn make_node(ctx: Context) -> Result<Node> {
/// let node = Node::builder().with_identities_storage(Arc::new(LmdbStorage::new("identities".into()))).build(ctx).await?;
/// let lmdb_storage = Arc::new(LmdbStorage::new("identities").await?);
/// let node = Node::builder().with_identities_storage(lmdb_storage).build(ctx).await?;
/// Ok(node)
/// }
/// ```
Expand Down
6 changes: 6 additions & 0 deletions implementations/rust/ockam/ockam_abac/Cargo.toml
Expand Up @@ -23,22 +23,28 @@ std = [
"minicbor/std",
"tracing/std",
"either/use_std",
"lmdb",
"once_cell/std",
"regex",
"tokio",
"wast",
]
lmdb = ["tokio", "lmdb-rkv"]

[dependencies]
either = { version = "1.8.1", default-features = false }
lmdb-rkv = { version = "0.14.0", optional = true }
minicbor = { version = "0.19.0", features = ["derive", "alloc"] }
ockam_core = { version = "0.78.0", path = "../ockam_core", default-features = false }
ockam_executor = { version = "0.46.0", path = "../ockam_executor", default-features = false }
ockam_identity = { version = "0.72.0", path = "../ockam_identity", default-features = false }
once_cell = { version = "1.17.1", default-features = false, features = ["alloc"] }
# optional:
regex = { version = "1.7.1", default-features = false, optional = true }
rustyline = { version = "11.0.0", optional = true }
rustyline-derive = { version = "0.8.0", optional = true }
str-buf = "3.0.1"
tokio = { version = "1.27", default-features = false, optional = true, features = ["sync", "time", "rt", "rt-multi-thread", "macros"] }
tracing = { version = "0.1.34", default-features = false }
wast = { version = "56.0.0", default-features = false, optional = true }

Expand Down
7 changes: 7 additions & 0 deletions implementations/rust/ockam/ockam_abac/src/lib.rs
Expand Up @@ -16,6 +16,7 @@ mod parser;
pub mod attribute_access_control;
pub mod expr;
pub mod mem;
mod storage;

pub use attribute_access_control::AbacAccessControl;
pub use env::Env;
Expand All @@ -28,3 +29,9 @@ pub use types::{Action, Resource, Subject};

#[cfg(feature = "std")]
pub use parser::parse;

#[cfg(not(feature = "std"))]
pub use ockam_executor::tokio;

#[cfg(feature = "std")]
pub use tokio;
91 changes: 91 additions & 0 deletions implementations/rust/ockam/ockam_abac/src/storage/lmdb_storage.rs
@@ -0,0 +1,91 @@
use crate::tokio::task::{spawn_blocking, JoinError};
use crate::{Action, Expr, PolicyStorage, Resource};
use core::str;
use lmdb::{Cursor, Transaction};
use minicbor::{Decode, Encode};
use ockam_core::async_trait;
use ockam_core::compat::boxed::Box;
use ockam_core::compat::fmt::Vec;
use ockam_core::errcode::{Kind, Origin};
use ockam_core::{Error, Result};
use ockam_identity::LmdbStorage;
use std::borrow::Cow;
use tracing as log;

/// Policy storage entry.
///
/// Used instead of storing plain `Expr` values to allow for additional
/// metadata, versioning, etc.
#[derive(Debug, Encode, Decode)]
#[rustfmt::skip]
struct PolicyEntry<'a> {
#[b(0)] expr: Cow<'a, Expr>,
}

#[async_trait]
impl PolicyStorage for LmdbStorage {
async fn get_policy(&self, r: &Resource, a: &Action) -> Result<Option<Expr>> {
let d = self.clone();
let k = format!("{r}:{a}");
let t = move || {
let r = d.env.begin_ro_txn().map_err(map_lmdb_err)?;
match r.get(d.map, &k) {
Ok(value) => {
let e: PolicyEntry = minicbor::decode(value)?;
Ok(Some(e.expr.into_owned()))
}
Err(lmdb::Error::NotFound) => Ok(None),
Err(e) => Err(map_lmdb_err(e)),
}
};
spawn_blocking(t).await.map_err(map_join_err)?
}

async fn set_policy(&self, r: &Resource, a: &Action, c: &Expr) -> Result<()> {
let v = minicbor::to_vec(PolicyEntry {
expr: Cow::Borrowed(c),
})?;
self.write(format!("{r}:{a}"), v).await
}

async fn del_policy(&self, r: &Resource, a: &Action) -> Result<()> {
self.delete(format!("{r}:{a}")).await
}

async fn policies(&self, r: &Resource) -> Result<Vec<(Action, Expr)>> {
let d = self.clone();
let r = r.clone();
let t = move || {
let tx = d.env.begin_ro_txn().map_err(map_lmdb_err)?;
let mut c = tx.open_ro_cursor(d.map).map_err(map_lmdb_err)?;
let mut xs = Vec::new();
for entry in c.iter_from(r.as_str()) {
let (k, v) = entry.map_err(map_lmdb_err)?;
let ks = str::from_utf8(k).map_err(from_utf8_err)?;
if let Some((prefix, a)) = ks.split_once(':') {
if prefix != r.as_str() {
break;
}
let x: PolicyEntry = minicbor::decode(v)?;
xs.push((Action::new(a), x.expr.into_owned()))
} else {
log::warn!(key = %ks, "malformed key in policy database")
}
}
Ok(xs)
};
spawn_blocking(t).await.map_err(map_join_err)?
}
}

fn map_join_err(err: JoinError) -> Error {
Error::new(Origin::Application, Kind::Io, err)
}

fn map_lmdb_err(err: lmdb::Error) -> Error {
Error::new(Origin::Application, Kind::Io, err)
}

fn from_utf8_err(err: str::Utf8Error) -> Error {
Error::new(Origin::Other, Kind::Invalid, err)
}
5 changes: 5 additions & 0 deletions implementations/rust/ockam/ockam_abac/src/storage/mod.rs
@@ -0,0 +1,5 @@
#[cfg(feature = "std")]
pub mod lmdb_storage;

#[cfg(feature = "std")]
pub use lmdb_storage::*;
3 changes: 1 addition & 2 deletions implementations/rust/ockam/ockam_abac/src/traits.rs
@@ -1,5 +1,4 @@
use crate::expr::Expr;
use crate::types::{Action, Resource};
use crate::{Action, Expr, Resource};
use ockam_core::async_trait;
use ockam_core::compat::boxed::Box;
use ockam_core::compat::vec::Vec;
Expand Down
5 changes: 1 addition & 4 deletions implementations/rust/ockam/ockam_api/Cargo.toml
Expand Up @@ -25,10 +25,8 @@ std = [
]
tag = ["cddl-cat", "once_cell", "ockam_core/tag"]
vault-storage = ["ockam_vault/storage"]
lmdb = ["std", "lmdb-rkv"]
authenticators = ["direct-authenticator"]
direct-authenticator = ["lmdb", "std"]
default = ["lmdb"]
direct-authenticator = ["std"]

[dependencies]
anyhow = "1"
Expand All @@ -39,7 +37,6 @@ dirs = "5.0.0"
either = { version = "1.8.1", default-features = false }
hex = { version = "0.4.3", default-features = false, features = ["alloc", "serde"] }
kafka-protocol = "0.6.0"
lmdb-rkv = { version = "0.14.0", optional = true }
lru = "0.10.0"
minicbor = { version = "0.19.0", features = ["alloc", "derive"] }
nix = "0.26"
Expand Down
7 changes: 3 additions & 4 deletions implementations/rust/ockam/ockam_api/src/cli_state.rs
Expand Up @@ -5,12 +5,15 @@ use crate::config::lookup::ProjectLookup;
use crate::nodes::models::transport::{CreateTransportJson, TransportMode, TransportType};

use nix::errno::Errno;
use ockam::identity::credential::Credential;
use ockam::identity::identity::{IdentityChangeHistory, IdentityHistoryComparison};
use ockam::identity::{
Identities, IdentitiesRepository, IdentitiesStorage, IdentitiesVault, Identity,
IdentityIdentifier,
};
use ockam_core::compat::sync::Arc;
use ockam_core::env::get_env_with_default;
use ockam_identity::LmdbStorage;
use ockam_vault::{storage::FileStorage, Vault};
use rand::random;
use serde::{Deserialize, Serialize};
Expand All @@ -19,10 +22,6 @@ use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::time::SystemTime;
use sysinfo::{Pid, System, SystemExt};

use crate::lmdb::LmdbStorage;
use ockam::identity::credential::Credential;
use ockam_core::env::get_env_with_default;
use thiserror::Error;

type Result<T> = std::result::Result<T, CliStateError>;
Expand Down
3 changes: 0 additions & 3 deletions implementations/rust/ockam/ockam_api/src/lib.rs
Expand Up @@ -23,9 +23,6 @@ mod util;

pub use util::*;

#[cfg(feature = "lmdb")]
pub mod lmdb;

#[macro_use]
extern crate tracing;

Expand Down
@@ -1,7 +1,6 @@
use crate::authenticator::direct::EnrollmentTokenAuthenticator;
use crate::bootstrapped_identities_store::BootstrapedIdentityStore;
use crate::echoer::Echoer;
use crate::lmdb::LmdbStorage;
use crate::nodes::authority_node::authority::EnrollerCheck::{AnyMember, EnrollerOnly};
use crate::nodes::authority_node::Configuration;
use crate::{actions, DefaultAddress};
Expand All @@ -15,7 +14,7 @@ use ockam_core::compat::sync::Arc;
use ockam_core::errcode::{Kind, Origin};
use ockam_core::flow_control::{FlowControlId, FlowControlPolicy, FlowControls};
use ockam_core::{Address, AllowAll, Error, Message, Result, Worker};
use ockam_identity::CredentialsIssuer;
use ockam_identity::{CredentialsIssuer, LmdbStorage};
use ockam_node::{Context, WorkerBuilder};
use ockam_transport_tcp::{TcpListenerOptions, TcpTransport};
use ockam_vault::storage::FileStorage;
Expand Down
5 changes: 5 additions & 0 deletions implementations/rust/ockam/ockam_identity/Cargo.toml
Expand Up @@ -37,8 +37,11 @@ std = [
"serde_bare/std",
"minicbor/std",
"time/std",
"lmdb",
]

lmdb = ["tokio-retry", "lmdb-rkv"]

# Feature: "no_std" enables functionality required for platforms
# without the standard library.
no_std = [
Expand Down Expand Up @@ -66,6 +69,7 @@ cfg-if = "1.0.0"
group = { version = "0.13.0", default-features = false }
heapless = "0.7"
hex = { version = "0.4", default-features = false }
lmdb-rkv = { version = "0.14.0", optional = true }
minicbor = { version = "0.19.0", features = ["alloc", "derive"] }
ockam_core = { path = "../ockam_core", version = "^0.78.0", default-features = false }
ockam_key_exchange_xx = { path = "../ockam_key_exchange_xx", version = "^0.74.0", default-features = false, optional = true }
Expand All @@ -80,6 +84,7 @@ serde_json = { version = "1.0", optional = true }
sha2 = { version = "0.10", default-features = false }
subtle = { version = "2.4.1", default-features = false }
time = { version = "0.3.20", features = ["macros", "formatting", "std"], optional = true }
tokio-retry = { version = "0.3.0", default-features = false, optional = true }
tracing = { version = "0.1", default_features = false }

[dev-dependencies]
Expand Down

0 comments on commit 7f21117

Please sign in to comment.