use async_trait::async_trait;
use clap::Args;
use colorful::Colorful;
use ockam::identity::Identifier;
use ockam::Context;
use ockam_api::authenticator::direct::Members;
use ockam_api::fmt_ok;
use ockam_api::nodes::InMemoryNode;
use ockam_multiaddr::MultiAddr;
use crate::project_member::{create_authority_client, create_member_attributes, get_project};
use crate::util::api::{IdentityOpts, RetryOpts};
use crate::{docs, Command, CommandGlobalOpts, Error};
const LONG_ABOUT: &str = include_str!("./static/add/long_about.txt");
const AFTER_LONG_HELP: &str = include_str!("./static/add/after_long_help.txt");
pub const OCKAM_RELAY_ATTRIBUTE: &str = "ockam-relay";
#[derive(Clone, Debug, Args)]
#[command(
long_about = docs::about(LONG_ABOUT),
after_long_help = docs::after_help(AFTER_LONG_HELP),
)]
pub struct AddCommand {
#[command(flatten)]
identity_opts: IdentityOpts,
#[arg(long, short, value_name = "ROUTE_TO_PROJECT")]
to: Option<MultiAddr>,
#[arg(value_name = "IDENTIFIER")]
member: Identifier,
#[arg(short, long = "attribute", value_name = "ATTRIBUTE")]
attributes: Vec<String>,
#[arg(long = "relay", value_name = "ENROLLEE_ALLOWED_RELAY_NAME")]
allowed_relay_name: Option<String>,
#[arg(long = "enroller")]
enroller: bool,
#[command(flatten)]
retry_opts: RetryOpts,
}
#[async_trait]
impl Command for AddCommand {
const NAME: &'static str = "project-member add";
fn retry_opts(&self) -> Option<RetryOpts> {
Some(self.retry_opts.clone())
}
async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> {
let project = get_project(&opts.state, &self.to).await?;
let node = InMemoryNode::start_with_project_name(
ctx,
&opts.state,
Some(project.name().to_string()),
)
.await?;
let authority_node_client =
create_authority_client(&node, &opts.state, &self.identity_opts, &project).await?;
authority_node_client
.add_member(
ctx,
self.member.clone(),
create_member_attributes(
&self.attributes,
&self.allowed_relay_name,
self.enroller,
)?,
)
.await
.map_err(Error::Retry)?;
opts.terminal.stdout().plain(fmt_ok!(
"Identifier {} is now a Project member. It can get a credential and access Project resources, like portals of other members",
self.member
));
Ok(())
}
}