commit - b2da4a0ec679e2071c2a3a981b5e8c5caef83235
commit + 57116925c93ae23cd81054de46b6197baf1d87d7
blob - 3249cffaf63d913464f8b8e339debdce16f38121
blob + 8fdc1f7149fecb0a57c4d26bfcd3a6590e3188ea
--- src/main.rs
+++ src/main.rs
run_sync(&common_args, &args).await?;
}
Commands::Add(args) => {
- // run_add_groups(args).await?;
+ run_add_groups(&common_args, args).await?;
println!("add");
} // Commands::Del(args) => {
// let common = CommonOperationArgs {
Ok(())
}
-// async fn run_add_groups(args: AddArgs) -> Result<()> {
-// // info!(
-// // pool_id = %args.pool_id,
-// // emails_file = ?args.emails_file,
-// // concurrency = ?args.concurrency,
-// // timeout = ?args.timeout,
-// // "add groups operation requested (not implemented yet)"
-// // );
+async fn run_add_groups(
+ common_args: &CommonOperationArgs,
+ cmd_args: AddArgs,
+) -> Result<()> {
+ info!(
+ pool_id = %common_args.pool_id,
+ emails_file = ?cmd_args.emails_file,
+ sync_file = ?cmd_args.sync_file,
+ groups = ?cmd_args.groups,
+ concurrency = ?common_args.concurrency,
+ timeout = ?common_args.timeout,
+ "add groups operation requested"
+ );
-// let config = aws_config::load_from_env().await;
-// let client = CognitoClient::new(&config);
+ let config = aws_config::load_from_env().await;
+ let client = CognitoClient::new(&config);
-// add_users_to_groups_from_files(
-// &args.pool_id,
-// &args.sync_file,
-// &args.emails_file,
-// &args.groups,
-// args.concurrency,
-// )
-// .await?;
+ add_users_to_groups_from_files(
+ &client,
+ &common_args.pool_id,
+ &cmd_args.sync_file,
+ &cmd_args.emails_file,
+ &cmd_args.groups,
+ common_args.concurrency,
+ )
+ .await?;
-// Ok(())
-// }
+ Ok(())
+}
// #[allow(dead_code)]
// async fn run_remove_groups(args: CommonOperationArgs) -> Result<()> {
Ok(emails)
}
-// /// Add a Cognito user to one or more groups using the Admin API.
-// ///
-// /// This function assumes AWS credentials and permissions allow admin operations.
-// pub async fn admin_add_user_to_groups(
-// client: &CognitoClient,
-// pool_id: &str,
-// username: &str,
-// groups: &[String],
-// ) -> Result<()> {
-// for group in groups {
-// info!(%username, %group, %pool_id, "adding user to Cognito group");
+/// Add a Cognito user to one or more groups using the Admin API.
+///
+/// This function assumes AWS credentials and permissions allow admin operations.
+pub async fn admin_add_user_to_groups(
+ client: &CognitoClient,
+ pool_id: &str,
+ username: &str,
+ groups: &[String],
+) -> Result<()> {
+ for group in groups {
+ info!(%username, %group, %pool_id, "adding user to Cognito group");
-// client
-// .admin_add_user_to_group()
-// .user_pool_id(pool_id)
-// .username(username)
-// .group_name(group)
-// .send()
-// .await
-// .with_context(|| {
-// format!(
-// "failed to add user '{}' to group '{}'",
-// username, group
-// )
-// })?;
+ client
+ .admin_add_user_to_group()
+ .user_pool_id(pool_id)
+ .username(username)
+ .group_name(group)
+ .send()
+ .await
+ .with_context(|| {
+ format!(
+ "failed to add user '{}' to group '{}'",
+ username, group
+ )
+ })?;
-// info!(%username, %group, "user successfully added to group");
-// }
+ info!(%username, %group, "user successfully added to group");
+ }
-// Ok(())
-// }
+ Ok(())
+}
-// /// High-level flow:
-// /// 1. Load sync CSV into HashMap<email, username>.
-// /// 2. Load target e-mails (one per line).
-// /// 3. For each email, find username in HashMap.
-// /// 4. Call `admin_add_user_to_groups` with concurrency limit.
-// /// 5. Log success or failure for each email.
-// ///
-// /// `sync_csv_path`: CSV generated by `sync` (username,email).
-// /// `emails_list_path`: TXT file with one e-mail per line (users to be added).
-// pub async fn add_users_to_groups_from_files(
-// client: &CognitoClient,
-// pool_id: &str,
-// sync_csv_path: &Path,
-// emails_list_path: &Path,
-// groups: &[String],
-// concurrency: usize,
-// ) -> Result<()> {
-// let concurrency = std::cmp::max(1, concurrency);
+/// High-level flow:
+/// 1. Load sync CSV into HashMap<email, username>.
+/// 2. Load target e-mails (one per line).
+/// 3. For each email, find username in HashMap.
+/// 4. Call `admin_add_user_to_groups` with concurrency limit.
+/// 5. Log success or failure for each email.
+///
+/// `sync_csv_path`: CSV generated by `sync` (username,email).
+/// `emails_list_path`: TXT file with one e-mail per line (users to be added).
+pub async fn add_users_to_groups_from_files(
+ client: &CognitoClient,
+ pool_id: &str,
+ sync_csv_path: &Path,
+ emails_list_path: &Path,
+ groups: &[String],
+ concurrency: usize,
+) -> Result<()> {
+ let concurrency = std::cmp::max(1, concurrency);
-// // 1. Load sync CSV into map: email -> username
-// let email_to_username = read_sync_file_to_map(sync_csv_path).await?;
-// info!(
-// total_entries = email_to_username.len(),
-// "loaded sync map (email -> username)"
-// );
+ // 1. Load sync CSV into map: email -> username
+ let email_to_username = read_sync_file_to_map(sync_csv_path).await?;
+ info!(
+ total_entries = email_to_username.len(),
+ "loaded sync map (email -> username)"
+ );
-// // 2. Load target e-mails
-// let emails = load_email_list(emails_list_path).await?;
-// let total_emails = emails.len();
-// info!(total_emails, "loaded target e-mail list");
+ // 2. Load target e-mails
+ let emails = load_email_list(emails_list_path).await?;
+ let total_emails = emails.len();
+ info!(total_emails, "loaded target e-mail list");
-// let pb = Arc::new({
-// let bar = ProgressBar::new(total_emails as u64);
-// bar.set_style(
-// ProgressStyle::with_template(
-// "[{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} {msg}",
-// )
-// .unwrap_or_else(|_| ProgressStyle::default_bar()),
-// );
-// bar.set_message("processing users");
-// bar
-// });
+ let pb = Arc::new({
+ let bar = ProgressBar::new(total_emails as u64);
+ bar.set_style(
+ ProgressStyle::with_template(
+ "[{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} {msg}",
+ )
+ .unwrap_or_else(|_| ProgressStyle::default_bar()),
+ );
+ bar.set_message("processing users");
+ bar
+ });
-// let semaphore = Arc::new(Semaphore::new(concurrency));
-// let mut handles: Vec<JoinHandle<()>> = Vec::with_capacity(emails.len());
+ let semaphore = Arc::new(Semaphore::new(concurrency));
+ let mut handles: Vec<JoinHandle<()>> = Vec::with_capacity(emails.len());
-// for email in emails {
-// let username = match email_to_username.get(&email) {
-// Some(u) => u.clone(),
-// None => {
-// error!(%email, "e-mail not found in sync map, skipping");
-// continue;
-// }
-// };
+ for email in emails {
+ let username = match email_to_username.get(&email) {
+ Some(u) => u.clone(),
+ None => {
+ error!(%email, "e-mail not found in sync map, skipping");
+ continue;
+ }
+ };
-// let permit = semaphore.clone().acquire_owned().await?;
-// let client_clone = client.clone();
-// let pool_id = pool_id.to_string();
-// let groups = groups.to_vec();
-// let email_clone = email.clone();
-// let pb_clone = pb.clone();
+ let permit = semaphore.clone().acquire_owned().await?;
+ let client_clone = client.clone();
+ let pool_id = pool_id.to_string();
+ let groups = groups.to_vec();
+ let email_clone = email.clone();
+ let pb_clone = pb.clone();
-// let handle = tokio::spawn(async move {
-// let _permit = permit; // keep permit alive for the duration of this task
+ let handle = tokio::spawn(async move {
+ let _permit = permit; // keep permit alive for the duration of this task
-// if let Err(err) = admin_add_user_to_groups(
-// &client_clone,
-// &pool_id,
-// &username,
-// &groups,
-// )
-// .await
-// {
-// error!(
-// email = %email_clone,
-// %username,
-// error = ?err,
-// "failed to add user to one or more groups"
-// );
-// } else {
-// info!(
-// email = %email_clone,
-// %username,
-// groups = ?groups,
-// "user successfully processed for all groups"
-// );
-// }
+ if let Err(err) = admin_add_user_to_groups(
+ &client_clone,
+ &pool_id,
+ &username,
+ &groups,
+ )
+ .await
+ {
+ error!(
+ email = %email_clone,
+ %username,
+ error = ?err,
+ "failed to add user to one or more groups"
+ );
+ } else {
+ info!(
+ email = %email_clone,
+ %username,
+ groups = ?groups,
+ "user successfully processed for all groups"
+ );
+ }
-// pb_clone.inc(1);
-// });
+ pb_clone.inc(1);
+ });
-// handles.push(handle);
-// }
+ handles.push(handle);
+ }
-// // Wait for all tasks to complete
-// for handle in handles {
-// // Ignore panics here, just surface as error logs.
-// if let Err(join_err) = handle.await {
-// error!(error = ?join_err, "join error while processing a user");
-// }
-// }
+ // Wait for all tasks to complete
+ for handle in handles {
+ // Ignore panics here, just surface as error logs.
+ if let Err(join_err) = handle.await {
+ error!(error = ?join_err, "join error while processing a user");
+ }
+ }
-// pb.finish_with_message("done");
-// info!("finished processing all users for add-groups operation");
-// Ok(())
-// }
+ pb.finish_with_message("done");
+ info!("finished processing all users for add-groups operation");
+ Ok(())
+}