Skip to content

Commit

Permalink
feat(rust): implemented ockam proxy vault
Browse files Browse the repository at this point in the history
  • Loading branch information
davide-baldo committed Nov 26, 2024
1 parent 108f126 commit 825f72e
Show file tree
Hide file tree
Showing 52 changed files with 2,060 additions and 245 deletions.
11 changes: 5 additions & 6 deletions implementations/rust/ockam/ockam_api/src/cli_state/cli_state.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use rand::random;
use std::path::{Path, PathBuf};
use tokio::sync::broadcast::{channel, Receiver, Sender};

use ockam::SqlxDatabase;
use ockam_core::env::get_env_with_default;
use ockam_node::database::DatabaseConfiguration;
use ockam_node::Executor;
use rand::random;
use std::path::{Path, PathBuf};
use tokio::sync::broadcast::{channel, Receiver, Sender};

use crate::cli_state::error::Result;
use crate::cli_state::CliStateError;
Expand Down Expand Up @@ -342,10 +341,10 @@ mod tests {

// create 2 identities
let identity1 = cli
.create_identity_with_name_and_vault("identity1", "vault1")
.create_identity_with_name_and_vault(None, "identity1", "vault1")
.await?;
let identity2 = cli
.create_identity_with_name_and_vault("identity2", "vault2")
.create_identity_with_name_and_vault(None, "identity2", "vault2")
.await?;

// create 2 nodes
Expand Down
66 changes: 48 additions & 18 deletions implementations/rust/ockam/ockam_api/src/cli_state/identities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use ockam::identity::models::ChangeHistory;
use ockam::identity::{Identifier, Identity};
use ockam_core::errcode::{Kind, Origin};
use ockam_core::Error;
use ockam_node::Context;
use ockam_vault::{HandleToSecret, SigningSecretKeyHandle};

use crate::cli_state::{random_name, CliState, Result};
Expand Down Expand Up @@ -31,6 +32,7 @@ impl CliState {
#[instrument(skip_all, fields(name = %name, vault_name = %vault_name))]
pub async fn create_identity_with_name_and_vault(
&self,
context: Option<&Context>,
name: &str,
vault_name: &str,
) -> Result<NamedIdentity> {
Expand All @@ -39,7 +41,9 @@ impl CliState {
};

let vault = self.get_named_vault(vault_name).await?;
let identities = self.make_identities(self.make_vault(vault).await?).await?;
let vault = self.make_vault(context, vault).await?;

let identities = self.make_identities(vault).await?;
let identity = identities.identities_creation().create_identity().await?;
let named_identity = self
.store_named_identity(&identity, name, vault_name)
Expand All @@ -65,9 +69,13 @@ impl CliState {
/// Create an identity associated with a name, using the default vault
/// If there is already an identity with that name, return its identifier
#[instrument(skip_all, fields(name = %name))]
pub async fn create_identity_with_name(&self, name: &str) -> Result<NamedIdentity> {
pub async fn create_identity_with_name(
&self,
context: Option<&Context>,
name: &str,
) -> Result<NamedIdentity> {
let vault = self.get_or_create_default_named_vault().await?;
self.create_identity_with_name_and_vault(name, &vault.name())
self.create_identity_with_name_and_vault(context, name, &vault.name())
.await
}

Expand All @@ -77,6 +85,7 @@ impl CliState {
#[instrument(skip_all, fields(name = %name, vault_name = %vault_name, key_id = %key_id))]
pub async fn create_identity_with_key_id(
&self,
context: Option<&Context>,
name: &str,
vault_name: &str,
key_id: &str,
Expand All @@ -96,8 +105,10 @@ impl CliState {
key_id.as_bytes().to_vec(),
));

let vault = self.make_vault(context, vault).await?;

// create the identity
let identities = self.make_identities(self.make_vault(vault).await?).await?;
let identities = self.make_identities(vault).await?;
let identifier = identities
.identities_creation()
.identity_builder()
Expand Down Expand Up @@ -154,13 +165,14 @@ impl CliState {
#[instrument(skip_all, fields(name = name.clone()))]
pub async fn get_named_identity_or_default(
&self,
context: Option<&Context>,
name: &Option<String>,
) -> Result<NamedIdentity> {
match name {
// Identity specified.
Some(name) => self.get_named_identity(name).await,
// No identity specified.
None => self.get_or_create_default_named_identity().await,
None => self.get_or_create_default_named_identity(context).await,
}
}

Expand Down Expand Up @@ -191,7 +203,11 @@ impl CliState {
/// Return a full identity from its name
/// Use the default identity if no name is given
#[instrument(skip_all, fields(name = name.clone()))]
pub async fn get_identity_by_optional_name(&self, name: &Option<String>) -> Result<Identity> {
pub async fn get_identity_by_optional_name(
&self,
context: Option<&Context>,
name: &Option<String>,
) -> Result<Identity> {
let named_identity = match name {
Some(name) => {
self.identities_repository()
Expand All @@ -209,7 +225,7 @@ impl CliState {
Some(identity) => {
let change_history = self.get_change_history(&identity.identifier()).await?;
let named_vault = self.get_named_vault(&identity.vault_name).await?;
let identity_vault = self.make_vault(named_vault).await?;
let identity_vault = self.make_vault(context, named_vault).await?;
Ok(Identity::import_from_change_history(
Some(&identity.identifier()),
change_history,
Expand Down Expand Up @@ -243,14 +259,23 @@ impl CliState {
/// Return the name of the default identity.
/// This function creates the default identity if it does not exist!
#[instrument(skip_all)]
pub async fn get_default_identity_name(&self) -> Result<String> {
Ok(self.get_or_create_default_named_identity().await?.name())
pub async fn get_or_create_default_identity_name(
&self,
context: Option<&Context>,
) -> Result<String> {
Ok(self
.get_or_create_default_named_identity(context)
.await?
.name())
}

/// Return the default named identity
/// This function creates the default identity if it does not exist!
#[instrument(skip_all)]
pub async fn get_or_create_default_named_identity(&self) -> Result<NamedIdentity> {
pub async fn get_or_create_default_named_identity(
&self,
context: Option<&Context>,
) -> Result<NamedIdentity> {
match self
.identities_repository()
.get_default_named_identity()
Expand All @@ -263,7 +288,8 @@ impl CliState {
self.notify_message(fmt_log!(
"There is no default Identity on this machine, generating one...\n"
));
self.create_identity_with_name(&random_name()).await
self.create_identity_with_name(context, &random_name())
.await
}
}
}
Expand All @@ -272,10 +298,14 @@ impl CliState {
/// - the given name if defined
/// - or the name of the default identity (which is created if it does not already exist!)
#[instrument(skip_all, fields(name = name.clone()))]
pub async fn get_identity_name_or_default(&self, name: &Option<String>) -> Result<String> {
pub async fn get_or_create_identity_name_or_default(
&self,
context: Option<&Context>,
name: &Option<String>,
) -> Result<String> {
match name {
Some(name) => Ok(name.clone()),
None => self.get_default_identity_name().await,
None => self.get_or_create_default_identity_name(context).await,
}
}

Expand Down Expand Up @@ -472,14 +502,14 @@ mod tests {
// then create an identity
let identity_name = "identity-name";
let identity = cli
.create_identity_with_name_and_vault(identity_name, vault_name)
.create_identity_with_name_and_vault(None, identity_name, vault_name)
.await?;
let expected = cli.get_named_identity(identity_name).await?;
assert_eq!(identity, expected);

// don't recreate the identity if it already exists with that name
let _ = cli
.create_identity_with_name_and_vault(identity_name, vault_name)
.create_identity_with_name_and_vault(None, identity_name, vault_name)
.await?;
let identities = cli.get_named_identities().await?;
assert_eq!(identities.len(), 1);
Expand All @@ -493,7 +523,7 @@ mod tests {

// create an identity using the default vault
let identity_name = "identity-name";
let identity = cli.create_identity_with_name(identity_name).await?;
let identity = cli.create_identity_with_name(None, identity_name).await?;
let expected = cli.get_named_identity(identity_name).await?;
assert_eq!(identity, expected);

Expand All @@ -509,7 +539,7 @@ mod tests {
let cli = CliState::test().await?;

// when we retrieve the default identity, we create it if it doesn't exist
let identity = cli.get_or_create_default_named_identity().await?;
let identity = cli.get_or_create_default_named_identity(None).await?;

// when the identity is created there is a change history + a named identity
let result = cli.get_change_history(&identity.identifier()).await;
Expand All @@ -528,7 +558,7 @@ mod tests {
#[tokio::test]
async fn test_delete_identity() -> Result<()> {
let cli = CliState::test().await?;
let identity = cli.create_identity_with_name("name").await?;
let identity = cli.create_identity_with_name(None, "name").await?;

// when the identity is created there is a change history + a named identity
let result = cli.get_change_history(&identity.identifier()).await;
Expand Down
46 changes: 24 additions & 22 deletions implementations/rust/ockam/ockam_api/src/cli_state/nodes.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
use crate::cli_state::{random_name, NamedVault, Result};
use crate::cli_state::{CliState, CliStateError};
use crate::cloud::project::Project;
use crate::colors::color_primary;
use crate::config::lookup::InternetAddress;
use crate::{fmt_warn, ConnectionStatus};

use colorful::Colorful;
use minicbor::{CborLen, Decode, Encode};
use nix::errno::Errno;
Expand All @@ -9,35 +16,29 @@ use ockam_core::errcode::{Kind, Origin};
use ockam_core::Error;
use ockam_multiaddr::proto::{DnsAddr, Node, Tcp};
use ockam_multiaddr::MultiAddr;
use ockam_node::Context;
use serde::Serialize;
use std::fmt::{Display, Formatter};
use std::path::PathBuf;
use std::process;
use std::time::Duration;
use sysinfo::{Pid, ProcessStatus, ProcessesToUpdate, System};

use crate::cli_state::{random_name, NamedVault, Result};
use crate::cli_state::{CliState, CliStateError};
use crate::cloud::project::Project;
use crate::colors::color_primary;
use crate::config::lookup::InternetAddress;

use crate::{fmt_warn, ConnectionStatus};

/// The methods below support the creation and update of local nodes
impl CliState {
/// Create a node, with some optional associated values, and start it
#[instrument(skip_all, fields(node_name = node_name, identity_name = identity_name.clone(), project_name = project_name.clone()
))]
pub async fn start_node_with_optional_values(
&self,
context: Option<&Context>,
node_name: &str,
identity_name: &Option<String>,
project_name: &Option<String>,
tcp_listener: Option<&TcpListener>,
) -> Result<NodeInfo> {
let mut node = self
.create_node_with_optional_values(node_name, identity_name, project_name)
.create_node_with_optional_values(context, node_name, identity_name, project_name)
.await?;
if node.pid.is_none() {
let pid = process::id();
Expand All @@ -61,13 +62,14 @@ impl CliState {
))]
pub async fn create_node_with_optional_values(
&self,
context: Option<&Context>,
node_name: &str,
identity_name: &Option<String>,
project_name: &Option<String>,
) -> Result<NodeInfo> {
let identity = match identity_name {
Some(name) => self.get_named_identity(name).await?,
None => self.get_or_create_default_named_identity().await?,
None => self.get_or_create_default_named_identity(context).await?,
};
let node = self
.create_node_with_identifier(node_name, &identity.identifier())
Expand All @@ -78,9 +80,8 @@ impl CliState {

/// This method creates a node with an associated identity
/// The vault used to create the identity is the default vault
#[instrument(skip_all, fields(node_name = node_name))]
pub async fn create_node(&self, node_name: &str) -> Result<NodeInfo> {
let identity = self.create_identity_with_name(&random_name()).await?;
pub async fn create_test_node(&self, node_name: &str) -> Result<NodeInfo> {
let identity = self.create_identity_with_name(None, &random_name()).await?;
self.create_node_with_identifier(node_name, &identity.identifier())
.await
}
Expand Down Expand Up @@ -712,7 +713,7 @@ mod tests {

// a node can be created with just a name
let node_name = "node-1";
let result = cli.create_node(node_name).await?;
let result = cli.create_test_node(node_name).await?;
assert_eq!(result.name(), node_name.to_string());

// the first node is the default one
Expand All @@ -723,7 +724,7 @@ mod tests {
let result = cli.get_or_create_default_named_vault().await.ok();
assert!(result.is_some());

let result = cli.get_or_create_default_named_identity().await.ok();
let result = cli.get_or_create_default_named_identity(None).await.ok();
assert!(result.is_some());

// that identity is associated to the node
Expand All @@ -739,15 +740,15 @@ mod tests {

// create a node
let node_name = "node-1";
let _ = cli.create_node(node_name).await?;
let _ = cli.create_test_node(node_name).await?;
cli.set_tcp_listener_address(
node_name,
&SocketAddr::from_str("127.0.0.1:0").unwrap().into(),
)
.await?;

// recreate the node with the same name
let _ = cli.create_node(node_name).await?;
let _ = cli.create_test_node(node_name).await?;

// the node must still be the default node
let result = cli.get_default_node().await?;
Expand All @@ -768,7 +769,7 @@ mod tests {

// a node can be created with just a name
let node1 = "node-1";
let node_info1 = cli.create_node(node1).await?;
let node_info1 = cli.create_test_node(node1).await?;

// the created node is set as the default node
let result = cli.get_default_node().await?;
Expand All @@ -777,7 +778,7 @@ mod tests {
// a node can also be removed
// first let's create a second node
let node2 = "node-2";
let node_info2 = cli.create_node(node2).await?;
let node_info2 = cli.create_test_node(node2).await?;

// and remove node 1
cli.remove_node(node1).await?;
Expand All @@ -804,15 +805,15 @@ mod tests {

// a node can be created with just a name
let node = cli
.create_node_with_optional_values("node-1", &None, &None)
.create_node_with_optional_values(None, "node-1", &None, &None)
.await?;
let result = cli.get_node(&node.name()).await?;
assert_eq!(result.name(), node.name());

// a node can be created with a name and an existing identity
let identity = cli.create_identity_with_name("name").await?;
let identity = cli.create_identity_with_name(None, "name").await?;
let node = cli
.create_node_with_optional_values("node-2", &Some(identity.name()), &None)
.create_node_with_optional_values(None, "node-2", &Some(identity.name()), &None)
.await?;
let result = cli.get_node(&node.name()).await?;
assert_eq!(result.identifier(), identity.identifier());
Expand Down Expand Up @@ -842,6 +843,7 @@ mod tests {

let node = cli
.create_node_with_optional_values(
None,
"node-4",
&Some(identity.name()),
&Some(project.name.clone()),
Expand Down
Loading

0 comments on commit 825f72e

Please sign in to comment.