use silicon_iam_client::models;
use crate::{
cli::InviteCommand,
context::Context,
error::{CliError, Result},
output::{Format, Table, json, label, next_cursor, timestamp},
};
#[allow(
clippy::too_many_lines,
reason = "one arm per verb; splitting the match would only move it elsewhere"
)]
pub async fn run(context: &Context, command: InviteCommand) -> Result<()> {
let client = context.authenticated().await?;
let org = context.organization()?;
match command {
InviteCommand::List { status, page } => {
let listed = client
.invitations()
.list(org, status.as_deref(), &page.paging())
.await?;
match context.format {
Format::Json => json(&listed),
Format::Text => {
let mut table = Table::new(["id", "invitee", "status", "expires"]);
for invite in &listed.items {
table.row([
invite.id.to_string(),
invite.target_carbon.carbon_id.clone(),
label(&invite.status),
timestamp(invite.expires_at),
]);
}
table.print();
next_cursor(listed.page.has_more, listed.page.next_cursor.as_deref());
Ok(())
}
}
}
InviteCommand::Create {
carbon_id,
email,
job_role,
boundary,
level,
} => {
if carbon_id.is_none() && email.is_none() {
return Err(CliError::Usage("give --carbon-id or --email".to_owned()));
}
let created = client
.invitations()
.create(
org,
&models::CarbonInviteCreate {
carbon_id,
email,
job_role,
tag_ids: None,
first_silicon_membership_id: None,
extra_silicon_membership_ids: None,
default_trust: crate::commands::trust::trust_value(&boundary, &level)?,
tag_trust_overrides: None,
silicon_trust_overrides: None,
redirect_app_id: None,
},
&context.mutation(),
)
.await?;
report(context, &created)
}
InviteCommand::Show { invite_id } => {
let invite = client.invitations().get(org, invite_id).await?;
report(context, &invite)
}
InviteCommand::Revoke { invite_id } => {
let current = client.invitations().get(org, invite_id).await?;
client
.invitations()
.revoke(org, invite_id, current.version, &context.mutation())
.await?;
println!("Revoked {invite_id}.");
Ok(())
}
InviteCommand::Code { email } => {
let dispatched = client
.invitations()
.send_join_code(org, &email, &context.mutation())
.await?;
match context.format {
Format::Json => json(&dispatched),
Format::Text => {
println!("Sent a code for invitation {}.", dispatched.invite_id);
println!(
"Accept with `iam invite accept {} --code <code>`.",
dispatched.invite_id
);
Ok(())
}
}
}
InviteCommand::Accept { invite_id, code } => {
let membership = client
.invitations()
.join(
org,
&models::InvitationAcceptance {
invite_id,
verification_code: code,
},
&context.mutation(),
)
.await?;
match context.format {
Format::Json => json(&membership),
Format::Text => {
println!("Joined {} as {}.", membership.org_id, membership.job_role);
Ok(())
}
}
}
}
}
fn report(context: &Context, invite: &models::Invite) -> Result<()> {
match context.format {
Format::Json => json(invite),
Format::Text => {
let mut table = Table::new(["field", "value"]);
table.row(["id", &invite.id.to_string()]);
table.row(["invitee", &invite.target_carbon.carbon_id]);
table.row(["status", &label(&invite.status)]);
table.row(["expires", ×tamp(invite.expires_at)]);
table.row(["version", &invite.version.to_string()]);
table.print();
Ok(())
}
}
}