Skip to content

Commit

Permalink
feat: multitenancy create and remove wallet (#184)
Browse files Browse the repository at this point in the history
Signed-off-by: Berend Sliedrecht <[email protected]>
Co-authored-by: Jean-Louis Leysens <[email protected]>
  • Loading branch information
berendsliedrecht and jloleysens authored Jun 3, 2022
1 parent 9cb5c97 commit cc70871
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 3 deletions.
2 changes: 1 addition & 1 deletion crates/agent/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl Display for Error {
match self {
Error::AuthorizationFailed => write!(f, "Failed to authorize. Api-key or authorization token is either wrong or missing."),
Error::UnableToParseResponse => write!(f, "Unable to parse the response from the server. Is the cloudagent the correct version?"),
Error::UrlDoesNotExist => write!(f, "Path does not exist on agent URL. This can happen when querying by id and the id is not valid."),
Error::UrlDoesNotExist => write!(f, "Path does not exist on agent URL. This can happen when querying by id and the id is not valid or when attempting to use a feature that is not supported on the cloudagent."),
Error::UnknownResponseStatusCode(msg) => write!(f, "Received unknown status code from the server. Agent URL is likely incorrect. If the agent URL is correct, please report this error at https://github.com/animo/agent-cli/issues/new \nAdditional info: {}", msg),
Error::InternalServerError(status) => write!(f, "Internal Server Error (status code: {})!", status),
Error::UnreachableUrl => write!(f, "Provided url is unreachable. Is the provided agent URL valid?"),
Expand Down
3 changes: 3 additions & 0 deletions crates/agent/src/modules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ pub mod proof;

/// Schema module for a generic cloudagent
pub mod schema;

/// Multitenancy module for a generic cloudagent
pub mod multitenancy;
37 changes: 37 additions & 0 deletions crates/agent/src/modules/multitenancy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use async_trait::async_trait;

use crate::error::Result;
use serde::Deserialize;
use serde::Serialize;
use serde_json::Value;

/// Response of the `create` endpoint on the multitenancy module
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct MultitenancyCreateResponse {
/// Timestamp of when the subwallet was created
pub created_at: String,
/// The mode of the key management (managed, unmanaged)
pub key_management_mode: String,

/// More wallet information
pub settings: Value,

/// JWT
pub token: String,

/// Timestamp of when the last update happened to the wallet
pub updated_at: String,

/// The wallet id
pub wallet_id: String,
}

/// Multitenancy module for a generic cloudagent
#[async_trait]
pub trait MultitenancyModule {
/// Create a new subwallet
async fn create(&self) -> Result<MultitenancyCreateResponse>;

/// Remove a subwallet
async fn remove(&self, wallet_id: String) -> Result<()>;
}
4 changes: 4 additions & 0 deletions crates/cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use clap::{Parser, Subcommand};
use crate::help_strings::HelpStrings;

use crate::modules::automation::AutomationOptions;
use crate::modules::multitenancy::MultitenancyOptions;
use crate::modules::{
basic_message::BasicMessageOptions, configuration::ConfigurationOptions,
connection::ConnectionOptions, credential::CredentialOptions,
Expand Down Expand Up @@ -83,4 +84,7 @@ pub enum Commands {

/// Proof subcommands
Proof(ProofOptions),

/// Multitenancy subcommnads
Multitenancy(MultitenancyOptions),
}
10 changes: 10 additions & 0 deletions crates/cli/src/help_strings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ pub enum HelpStrings {
ProofRequestAttribute,
ProofRequestConnectionId,

// Multitenancy
Multitenancy,
MultitenancyCreate,
MultitenancyRemove,
MultitenancyRemoveWalletId,

// Automate
Automation,
AutomationCredentialOffer,
Expand Down Expand Up @@ -200,6 +206,10 @@ impl HelpStrings {
HelpStrings::AutomationCredentialOfferNoQr => "Do not show a QR code",
HelpStrings::AutomationCredentialOfferSelf => "Offer a credential to self",
HelpStrings::AutomationCredentialOfferTimeout=> "Timeout in seconds",
HelpStrings::Multitenancy => "foo",
HelpStrings::MultitenancyCreate => "foo",
HelpStrings::MultitenancyRemove => "foo",
HelpStrings::MultitenancyRemoveWalletId => "foo",
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions crates/cli/src/modules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ pub mod proof;

/// Module for schemas
pub mod schema;

/// Module for multitenancy
pub mod multitenancy;
54 changes: 54 additions & 0 deletions crates/cli/src/modules/multitenancy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use crate::{
error::Result,
help_strings::HelpStrings,
utils::loader::{Loader, LoaderVariant},
};
use agent::modules::multitenancy::MultitenancyModule;
use clap::{Args, Subcommand};

/// Credential Definition options and flags
#[derive(Args)]
#[clap(about = "CRUD functionality with multitenancy wallets")]
pub struct MultitenancyOptions {
/// All the subcommands of the multitenancy cli
#[clap(subcommand)]
pub commands: MultitenancySubcommands,
}

/// Credential Definition subcommands
#[derive(Subcommand, Debug)]
pub enum MultitenancySubcommands {
/// Create a subwallet
#[clap(about = HelpStrings::MultitenancyCreate)]
Create {},

/// Remove a subwallet
#[clap(about = HelpStrings::MultitenancyRemove)]
Remove {
/// List a single credential definition by id
#[clap(long, short, help = HelpStrings::MultitenancyRemoveWalletId)]
wallet_id: String,
},
}

/// Subcommand multitenancy parser
pub async fn parse_multitenancy_args(
options: &MultitenancyOptions,
agent: impl MultitenancyModule,
) -> Result<()> {
let loader = Loader::start(LoaderVariant::default());

match &options.commands {
MultitenancySubcommands::Create {} => agent.create().await.map(|response| {
loader.stop();
copy!("{}", response.wallet_id);
log!("{}", response.wallet_id);
}),
MultitenancySubcommands::Remove { wallet_id } => {
agent.remove(wallet_id.to_owned()).await?;
loader.stop();
log!("Successfully removed wallet with id: {}", wallet_id);
Ok(())
}
}
}
11 changes: 11 additions & 0 deletions crates/cli/src/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::modules::basic_message::parse_basic_message_args;
use crate::modules::configuration::parse_configuration_args;
use crate::modules::credential::parse_credentials_args;
use crate::modules::credential_definition::parse_credential_definition_args;
use crate::modules::multitenancy::parse_multitenancy_args;
use crate::modules::proof::parse_proof_args;
use crate::modules::{
connection::parse_connection_args, feature::parse_features_args, schema::parse_schema_args,
Expand Down Expand Up @@ -105,6 +106,16 @@ pub async fn register() -> Result<()> {
)?;
parse_proof_args(&options.commands, agent).await
}
Commands::Multitenancy(options) => {
let agent = initialize_agent_from_cli(
cli.config,
cli.environment,
cli.agent_url,
cli.api_key,
cli.token,
)?;
parse_multitenancy_args(options, agent).await
}
Commands::Automate(options) => {
let agent = initialize_agent_from_cli(
cli.config,
Expand Down
3 changes: 3 additions & 0 deletions crates/cloudagent-python/src/agent_python/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ mod proof;

/// Module for schemas definitions specific for an Aries cloudagent Python
mod schema;

/// Module for multitenancy specific for an Aries cloudagent Python
mod multitenancy;
29 changes: 29 additions & 0 deletions crates/cloudagent-python/src/agent_python/multitenancy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use super::agent::CloudAgentPython;
use agent::modules::multitenancy::MultitenancyModule;
use agent::{error::Result, modules::multitenancy::MultitenancyCreateResponse};
use async_trait::async_trait;
use serde_json::{json, Value};

#[async_trait]
impl MultitenancyModule for CloudAgentPython {
/// TODO: this only returns the wallet id for now
async fn create(&self) -> Result<MultitenancyCreateResponse> {
let url = self
.cloud_agent
.create_url(vec!["multitenancy", "wallet"])?;

self.cloud_agent
.post::<MultitenancyCreateResponse>(url, None, Some(json!({})))
.await
}

async fn remove(&self, wallet_id: String) -> Result<()> {
let url =
self.cloud_agent
.create_url(vec!["multitenancy", "wallet", &wallet_id, "remove"])?;

self.cloud_agent.post::<Value>(url, None, None).await?;

Ok(())
}
}
2 changes: 1 addition & 1 deletion crates/cloudagent-python/src/cloud_agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub struct CloudAgent {
/// admin Api key for the cloudagent
pub api_key: Option<String>,

/// Authorization token for a mutli tenancy agent
/// Authorization token for a multi tenancy agent
pub auth_token: Option<String>,
}

Expand Down
2 changes: 1 addition & 1 deletion docker/docker-compose.acapy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ services:
--admin-insecure-mode \
--label 'tester_agent' \
--log-level 'info' ",
]
]

0 comments on commit cc70871

Please sign in to comment.