Skip to content

Commit

Permalink
refactor(rust): hide repositories
Browse files Browse the repository at this point in the history
  • Loading branch information
etorreborre committed Nov 20, 2023
1 parent 341caa6 commit 35f865d
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 105 deletions.
40 changes: 19 additions & 21 deletions implementations/rust/ockam/ockam_api/src/cli_state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ use miette::Diagnostic;
use rand::random;
use thiserror::Error;

use ockam::identity::storage::{PurposeKeysRepository, PurposeKeysSqlxDatabase};
use ockam::identity::{
ChangeHistoryRepository, ChangeHistorySqlxDatabase, Identities, IdentityAttributesRepository,
IdentityAttributesSqlxDatabase,
};
use ockam::identity::storage::{PurposeKeysRepository, PurposeKeysSqlxDatabase};
use ockam::SqlxDatabase;
use ockam_abac::{PoliciesRepository, PolicySqlxDatabase};
use ockam_core::compat::sync::Arc;
use ockam_core::env::get_env_with_default;
use ockam_core::Error;
use ockam_node::Executor;
use ockam_vault::storage::{SecretsRepository, SecretsSqlxDatabase};
pub use projects_repository::*;
pub use projects_repository_sql::*;
pub use spaces_repository::*;
Expand Down Expand Up @@ -42,9 +42,11 @@ pub mod credentials;
pub mod enrollments;
pub mod identities;
pub mod nodes;
pub mod policies;
pub mod projects;
pub mod projects_repository;
pub mod projects_repository_sql;
pub mod secure_channels;
pub mod spaces;
pub mod spaces_repository;
pub mod spaces_repository_sql;
Expand Down Expand Up @@ -74,8 +76,8 @@ pub enum CliStateError {

#[error("A {resource} named {name} already exists")]
#[diagnostic(
code("OCK409"),
help("Please try using a different name or delete the existing {resource}")
code("OCK409"),
help("Please try using a different name or delete the existing {resource}")
)]
AlreadyExists { resource: String, name: String },

Expand All @@ -101,8 +103,8 @@ pub enum CliStateError {

#[error("Invalid configuration version '{0}'")]
#[diagnostic(
code("OCK500"),
help("Please try running 'ockam reset' to reset your local configuration")
code("OCK500"),
help("Please try running 'ockam reset' to reset your local configuration")
)]
InvalidVersion(String),
}
Expand All @@ -117,7 +119,7 @@ impl From<CliStateError> for ockam_core::Error {
fn from(e: CliStateError) -> Self {
match e {
CliStateError::Ockam(e) => e,
_ => ockam_core::Error::new(
_ => Error::new(
ockam_core::errcode::Origin::Application,
ockam_core::errcode::Kind::Internal,
e,
Expand Down Expand Up @@ -156,27 +158,23 @@ impl CliState {
self.dir.clone()
}

pub async fn change_history_repository(&self) -> Result<Arc<dyn ChangeHistoryRepository>> {
async fn change_history_repository(&self) -> Result<Arc<dyn ChangeHistoryRepository>> {
Ok(Arc::new(ChangeHistorySqlxDatabase::new(self.database())))
}

pub async fn secrets_repository(&self) -> Result<Arc<dyn SecretsRepository>> {
Ok(Arc::new(SecretsSqlxDatabase::new(self.database())))
}

pub async fn identity_attributes_repository(
async fn identity_attributes_repository(
&self,
) -> Result<Arc<dyn IdentityAttributesRepository>> {
Ok(Arc::new(IdentityAttributesSqlxDatabase::new(
self.database(),
)))
}

pub async fn identities_repository(&self) -> Result<Arc<dyn IdentitiesRepository>> {
async fn identities_repository(&self) -> Result<Arc<dyn IdentitiesRepository>> {
Ok(Arc::new(IdentitiesSqlxDatabase::new(self.database())))
}

pub async fn purpose_keys_repository(&self) -> Result<Arc<dyn PurposeKeysRepository>> {
async fn purpose_keys_repository(&self) -> Result<Arc<dyn PurposeKeysRepository>> {
Ok(Arc::new(PurposeKeysSqlxDatabase::new(self.database())))
}

Expand All @@ -192,27 +190,27 @@ impl CliState {
Ok(Arc::new(NodesSqlxDatabase::new(self.database())))
}

pub async fn policies_repository(&self) -> Result<Arc<dyn PoliciesRepository>> {
pub(super) async fn policies_repository(&self) -> Result<Arc<dyn PoliciesRepository>> {
Ok(Arc::new(PolicySqlxDatabase::new(self.database())))
}

pub async fn projects_repository(&self) -> Result<Arc<dyn ProjectsRepository>> {
async fn projects_repository(&self) -> Result<Arc<dyn ProjectsRepository>> {
Ok(Arc::new(ProjectsSqlxDatabase::new(self.database())))
}

pub async fn spaces_repository(&self) -> Result<Arc<dyn SpacesRepository>> {
async fn spaces_repository(&self) -> Result<Arc<dyn SpacesRepository>> {
Ok(Arc::new(SpacesSqlxDatabase::new(self.database())))
}

pub async fn users_repository(&self) -> Result<Arc<dyn UsersRepository>> {
async fn users_repository(&self) -> Result<Arc<dyn UsersRepository>> {
Ok(Arc::new(UsersSqlxDatabase::new(self.database())))
}

pub async fn credentials_repository(&self) -> Result<Arc<dyn CredentialsRepository>> {
async fn credentials_repository(&self) -> Result<Arc<dyn CredentialsRepository>> {
Ok(Arc::new(CredentialsSqlxDatabase::new(self.database())))
}

pub async fn trust_contexts_repository(&self) -> Result<Arc<dyn TrustContextsRepository>> {
async fn trust_contexts_repository(&self) -> Result<Arc<dyn TrustContextsRepository>> {
Ok(Arc::new(TrustContextsSqlxDatabase::new(self.database())))
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use std::sync::Arc;

use ockam::identity::{
ChangeHistoryRepository, IdentityAttributesRepository, SecureChannelRegistry, SecureChannels,
Vault,
ChangeHistoryRepository, IdentityAttributesRepository, SecureChannels, Vault,
};

use crate::bootstrapped_identities_store::{
Expand Down Expand Up @@ -46,20 +45,4 @@ impl CliState {
.build();
Ok(secure_channels)
}

/// Build a SecureChannels struct for a specific vault if one is specified
/// and reuse the secure_channel_registry
pub(crate) async fn build_secure_channels(
&self,
vault_name: &str,
secure_channel_registry: SecureChannelRegistry,
) -> Result<Arc<SecureChannels>> {
let vault = self.get_vault_by_name(vault_name).await?;
Ok(SecureChannels::builder()
.with_vault(vault)
.with_change_history_repository(self.change_history_repository().await?)
.with_secure_channels_registry(secure_channel_registry)
.with_purpose_keys_repository(self.purpose_keys_repository().await?)
.build())
}
}
67 changes: 13 additions & 54 deletions implementations/rust/ockam/ockam_api/src/nodes/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,21 @@ use minicbor::{Decoder, Encode};

use ockam::identity::models::CredentialAndPurposeKey;
use ockam::identity::TrustContext;
use ockam::identity::Vault;
use ockam::identity::{ChangeHistoryRepository, Credentials, CredentialsServer, Identities};
use ockam::identity::{Credentials, CredentialsServer, Identities};
use ockam::identity::{CredentialsServerModule, IdentityAttributesRepository};
use ockam::identity::{Identifier, SecureChannels};
use ockam::{
Address, Context, RelayService, RelayServiceOptions, Result, Routed, TcpTransport, Worker,
};
use ockam_abac::expr::{eq, ident, str};
use ockam_abac::{Action, Env, Expr, PoliciesRepository, PolicyAccessControl, Resource};
use ockam_abac::{Action, Env, Expr, Resource};
use ockam_core::api::{Method, RequestHeader, Response};
use ockam_core::compat::{string::String, sync::Arc};
use ockam_core::flow_control::FlowControlId;
use ockam_core::AllowAll;
use ockam_core::IncomingAccessControl;
use ockam_multiaddr::MultiAddr;

use crate::bootstrapped_identities_store::BootstrapedIdentityAttributesStore;
use crate::bootstrapped_identities_store::PreTrustedIdentities;
use crate::cli_state::trust_contexts_repository_sql::NamedTrustContext;
use crate::cli_state::CliState;
Expand Down Expand Up @@ -96,7 +94,6 @@ pub struct NodeManager {
pub(crate) secure_channels: Arc<SecureChannels>,
trust_context: Option<TrustContext>,
pub(crate) registry: Registry,
policies_repository: Arc<dyn PoliciesRepository>,
pub(crate) medic_handle: MedicHandle,
}

Expand Down Expand Up @@ -140,10 +137,6 @@ impl NodeManager {
Arc::new(CredentialsServerModule::new(self.credentials()))
}

pub(super) fn secure_channels_vault(&self) -> Vault {
self.secure_channels.identities().vault()
}

pub fn tcp_transport(&self) -> &TcpTransport {
&self.tcp_transport
}
Expand Down Expand Up @@ -246,29 +239,19 @@ impl NodeManager {

// Check if a policy exists for (resource, action) and if not, then
// create or use a default entry:
if self.policies_repository.get_policy(r, a).await?.is_none() {
if self.cli_state.get_policy(r, a).await?.is_none() {
let fallback = match custom_default {
Some(e) => e.clone(),
None => eq([
ident("resource.trust_context_id"),
ident("subject.trust_context_id"),
]),
};
self.policies_repository.set_policy(r, a, &fallback).await?
self.cli_state.set_policy(r, a, &fallback).await?;
}
let policies = self.policies_repository.clone();
debug!(
"set a policy access control for resource '{}' and action '{}'",
&r, &a
);

Ok(Arc::new(PolicyAccessControl::new(
policies,
self.identity_attributes_repository(),
r.clone(),
a.clone(),
env,
)))
let policy_access_control =
self.cli_state.make_policy_access_control(r, a, env).await?;
Ok(Arc::new(policy_access_control))
} else {
debug!(
"no policy access control set for resource '{}' and action: '{}'",
Expand Down Expand Up @@ -371,35 +354,12 @@ impl NodeManager {
debug!("create the identity repository");
let cli_state = general_options.cli_state;

let change_history_repository: Arc<dyn ChangeHistoryRepository> =
cli_state.change_history_repository().await?;
let identity_attributes_repository: Arc<dyn IdentityAttributesRepository> =
cli_state.identity_attributes_repository().await?;
let policies_repository: Arc<dyn PoliciesRepository> =
cli_state.policies_repository().await?;

//TODO: fix this. Either don't require it to be a bootstrappedidentitystore (and use the
//trait instead), or pass it from the general_options always.
let vault: Vault = cli_state.get_node_vault(&general_options.node_name).await?;
let identity_attributes_repository: Arc<dyn IdentityAttributesRepository> =
Arc::new(match general_options.pre_trusted_identities {
None => BootstrapedIdentityAttributesStore::new(
Arc::new(PreTrustedIdentities::new_from_string("{}")?),
identity_attributes_repository.clone(),
),
Some(f) => BootstrapedIdentityAttributesStore::new(
Arc::new(f),
identity_attributes_repository.clone(),
),
});

debug!("create the secure channels service");
let secure_channels = SecureChannels::builder()
.with_vault(vault)
.with_change_history_repository(change_history_repository.clone())
.with_identity_attributes_repository(identity_attributes_repository.clone())
.with_purpose_keys_repository(cli_state.purpose_keys_repository().await?)
.build();
let secure_channels = cli_state
.secure_channels(
&general_options.node_name,
general_options.pre_trusted_identities,
)
.await?;

debug!("start the medic");
let medic_handle = MedicHandle::start_medic(ctx).await?;
Expand Down Expand Up @@ -429,7 +389,6 @@ impl NodeManager {
secure_channels,
trust_context,
registry: Default::default(),
policies_repository,
medic_handle,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -532,13 +532,14 @@ impl NodeManagerWorker {
// if we are using the project we need to allow safe communication based on the
// project identifier
self.node_manager
.policies_repository
.cli_state
.set_policy(
&resources::INLET,
&actions::HANDLE_MESSAGE,
&eq([ident("subject.identifier"), str(project_identifier)]),
)
.await?;
.await
.map_err(ockam_core::Error::from)?
}
}

Expand Down
17 changes: 11 additions & 6 deletions implementations/rust/ockam/ockam_api/src/nodes/service/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ impl NodeManager {
let p: Policy = dec.decode()?;
let r = Resource::new(resource);
let a = Action::new(action);
self.policies_repository
self.cli_state
.set_policy(&r, &a, p.expression())
.await?;
.await
.map_err(ockam_core::Error::from)?;
Ok(Response::ok(req))
}

Expand All @@ -37,7 +38,7 @@ impl NodeManager {
) -> Result<Either<Response<Error>, Response<Policy>>> {
let r = Resource::new(resource);
let a = Action::new(action);
if let Some(e) = self.policies_repository.get_policy(&r, &a).await? {
if let Some(e) = self.cli_state.get_policy(&r, &a).await? {
Ok(Either::Right(Response::ok(req).body(Policy::new(e))))
} else {
Ok(Either::Left(Response::not_found(req, "policy not found")))
Expand All @@ -51,9 +52,10 @@ impl NodeManager {
) -> Result<Response<PolicyList>, Response<Error>> {
let r = Resource::new(res);
let p = self
.policies_repository
.cli_state
.get_policies_by_resource(&r)
.await?;
.await
.map_err(ockam_core::Error::from)?;
let p = p.into_iter().map(|(a, e)| Expression::new(a, e)).collect();
Ok(Response::ok(req).body(PolicyList::new(p)))
}
Expand All @@ -66,7 +68,10 @@ impl NodeManager {
) -> Result<Response<()>, Response<Error>> {
let r = Resource::new(res);
let a = Action::new(act);
self.policies_repository.delete_policy(&r, &a).await?;
self.cli_state
.delete_policy(&r, &a)
.await
.map_err(ockam_core::Error::from)?;
Ok(Response::ok(req))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -506,13 +506,18 @@ impl NodeManager {
return Ok(self.secure_channels.clone());
}
let vault = self.get_secure_channels_vault(vault_name.clone()).await?;
let identity_repository = self.cli_state.change_history_repository().await?;
let registry = self.secure_channels.secure_channel_registry();
Ok(SecureChannels::builder()
.with_vault(vault)
.with_change_history_repository(identity_repository)
.with_change_history_repository(
self.secure_channels
.identities()
.change_history_repository(),
)
.with_purpose_keys_repository(
self.secure_channels.identities().purpose_keys_repository(),
)
.with_secure_channels_registry(registry)
.with_purpose_keys_repository(self.cli_state.purpose_keys_repository().await?)
.build())
}

Expand All @@ -521,7 +526,7 @@ impl NodeManager {
let existing_vault = self.cli_state.get_vault_by_name(&vault_name).await?;
Ok(existing_vault)
} else {
Ok(self.secure_channels_vault())
Ok(self.secure_channels.vault())
}
}
}

0 comments on commit 35f865d

Please sign in to comment.