Skip to content

Commit 0a5ff9c

Browse files
authored
SM-807: BWS CLI & SDK Updates (#77)
* SM-807: Fix edit secret, allow updating the project a secret is in, and other small changes * SM-807: Update schemas * SM-807: Add proper error messaging when secrets or projects are deleted. * SM-807: Make project_id a parameter rather than an argument on secret create * SM-807: Add back project_ids that were lost in the merge conflict resolution * SM-807: Add additional secrets / projects deletion error message when there are errors * SM-807: Make failed messaging on projects or secrets delete optional, and other small output fixes * SM-807: Add back the project_id help text on secret create * SM-807: Update secret/project delete to use a filter_map and not print on 0 successes * SM-807: Remove mut refactor
1 parent 3bfaec3 commit 0a5ff9c

File tree

2 files changed

+69
-14
lines changed

2 files changed

+69
-14
lines changed

crates/bitwarden/src/secrets_manager/secrets/update.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub struct SecretPutRequest {
2020
pub key: String,
2121
pub value: String,
2222
pub note: String,
23+
pub project_ids: Option<Vec<Uuid>>,
2324
}
2425

2526
pub(crate) async fn update_secret(
@@ -37,7 +38,7 @@ pub(crate) async fn update_secret(
3738
key: enc.encrypt(input.key.as_bytes(), &org_id)?.to_string(),
3839
value: enc.encrypt(input.value.as_bytes(), &org_id)?.to_string(),
3940
note: enc.encrypt(input.note.as_bytes(), &org_id)?.to_string(),
40-
project_ids: None,
41+
project_ids: input.project_ids.clone(),
4142
});
4243

4344
let config = client.get_api_configurations().await;

crates/bws/src/main.rs

+67-13
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,16 @@ enum SecretCommand {
109109
key: String,
110110
value: String,
111111

112+
#[arg(help = "The ID of the project this secret will be added to")]
113+
project_id: Uuid,
114+
112115
#[arg(long, help = "An optional note to add to the secret")]
113116
note: Option<String>,
114-
115-
#[arg(long, help = "The ID of the project this secret will be added to")]
116-
project_id: Option<Uuid>,
117117
},
118118
Delete {
119119
secret_ids: Vec<Uuid>,
120120
},
121+
#[clap(group = ArgGroup::new("edit_field").required(true).multiple(true))]
121122
Edit {
122123
secret_id: Uuid,
123124
#[arg(long, group = "edit_field")]
@@ -126,6 +127,8 @@ enum SecretCommand {
126127
value: Option<String>,
127128
#[arg(long, group = "edit_field")]
128129
note: Option<String>,
130+
#[arg(long, group = "edit_field")]
131+
project_id: Option<Uuid>,
129132
},
130133
Get {
131134
secret_id: Uuid,
@@ -179,7 +182,7 @@ enum CreateCommand {
179182
note: Option<String>,
180183

181184
#[arg(long, help = "The ID of the project this secret will be added to")]
182-
project_id: Option<Uuid>,
185+
project_id: Uuid,
183186
},
184187
}
185188

@@ -200,6 +203,8 @@ enum EditCommand {
200203
value: Option<String>,
201204
#[arg(long, group = "edit_field")]
202205
note: Option<String>,
206+
#[arg(long, group = "edit_field")]
207+
project_id: Option<Uuid>,
203208
},
204209
}
205210

@@ -383,17 +388,34 @@ async fn process_commands() -> Result<()> {
383388
| Commands::Delete {
384389
cmd: DeleteCommand::Project { project_ids },
385390
} => {
386-
let project_count = project_ids.len();
391+
let count = project_ids.len();
387392

388-
client
393+
let result = client
389394
.projects()
390395
.delete(ProjectsDeleteRequest { ids: project_ids })
391396
.await?;
392397

393-
if project_count > 1 {
394-
println!("Projects deleted successfully.");
395-
} else {
396-
println!("Project deleted successfully.");
398+
let projects_failed: Vec<(Uuid, String)> = result
399+
.data
400+
.into_iter()
401+
.filter_map(|r| r.error.map(|e| (r.id, e)))
402+
.collect();
403+
let deleted_projects = count - projects_failed.len();
404+
405+
if deleted_projects > 1 {
406+
println!("{} projects deleted successfully.", deleted_projects);
407+
} else if deleted_projects == 1 {
408+
println!("{} project deleted successfully.", deleted_projects);
409+
}
410+
411+
if projects_failed.len() > 1 {
412+
println!("{} projects had errors:", projects_failed.len());
413+
} else if projects_failed.len() == 1 {
414+
println!("{} project had an error:", projects_failed.len());
415+
}
416+
417+
for project in projects_failed {
418+
println!("{}: {}", project.0, project.1);
397419
}
398420
}
399421

@@ -466,7 +488,7 @@ async fn process_commands() -> Result<()> {
466488
key,
467489
value,
468490
note: note.unwrap_or_default(),
469-
project_ids: project_id.map(|p| vec![p]),
491+
project_ids: Some(vec![project_id]),
470492
})
471493
.await?;
472494
serialize_response(secret, cli.output, color);
@@ -479,6 +501,7 @@ async fn process_commands() -> Result<()> {
479501
key,
480502
value,
481503
note,
504+
project_id,
482505
},
483506
}
484507
| Commands::Edit {
@@ -488,6 +511,7 @@ async fn process_commands() -> Result<()> {
488511
key,
489512
value,
490513
note,
514+
project_id,
491515
},
492516
} => {
493517
let old_secret = client
@@ -505,6 +529,13 @@ async fn process_commands() -> Result<()> {
505529
key: key.unwrap_or(old_secret.key),
506530
value: value.unwrap_or(old_secret.value),
507531
note: note.unwrap_or(old_secret.note),
532+
project_ids: match project_id {
533+
Some(id) => Some(vec![id]),
534+
None => match old_secret.project_id {
535+
Some(id) => Some(vec![id]),
536+
None => bail!("Editing a secret requires a project_id."),
537+
},
538+
},
508539
})
509540
.await?;
510541
serialize_response(secret, cli.output, color);
@@ -516,12 +547,35 @@ async fn process_commands() -> Result<()> {
516547
| Commands::Delete {
517548
cmd: DeleteCommand::Secret { secret_ids },
518549
} => {
519-
client
550+
let count = secret_ids.len();
551+
552+
let result = client
520553
.secrets()
521554
.delete(SecretsDeleteRequest { ids: secret_ids })
522555
.await?;
523556

524-
println!("Secret deleted correctly");
557+
let secrets_failed: Vec<(Uuid, String)> = result
558+
.data
559+
.into_iter()
560+
.filter_map(|r| r.error.map(|e| (r.id, e)))
561+
.collect();
562+
let deleted_secrets = count - secrets_failed.len();
563+
564+
if deleted_secrets > 1 {
565+
println!("{} secrets deleted successfully.", deleted_secrets);
566+
} else if deleted_secrets == 1 {
567+
println!("{} secret deleted successfully.", deleted_secrets);
568+
}
569+
570+
if secrets_failed.len() > 1 {
571+
println!("{} secrets had errors:", secrets_failed.len());
572+
} else if secrets_failed.len() == 1 {
573+
println!("{} secret had an error:", secrets_failed.len());
574+
}
575+
576+
for secret in secrets_failed {
577+
println!("{}: {}", secret.0, secret.1);
578+
}
525579
}
526580

527581
Commands::Config { .. } => {

0 commit comments

Comments
 (0)