diff --git a/crates/cli/src/commands/manage.rs b/crates/cli/src/commands/manage.rs index c59dca5a..f95d7edf 100644 --- a/crates/cli/src/commands/manage.rs +++ b/crates/cli/src/commands/manage.rs @@ -18,11 +18,13 @@ use mas_config::{DatabaseConfig, PasswordsConfig}; use mas_data_model::{Device, TokenType}; use mas_storage::{ compat::{CompatAccessTokenRepository, CompatSessionRepository}, + job::{JobRepositoryExt, ProvisionUserJob}, user::{UserEmailRepository, UserPasswordRepository, UserRepository}, Repository, RepositoryAccess, SystemClock, }; use mas_storage_pg::PgRepository; use rand::SeedableRng; +use sqlx::types::Uuid; use tracing::{info, info_span}; use crate::util::{database_from_config, password_manager_from_config}; @@ -54,6 +56,9 @@ enum Subcommand { #[arg(long = "yes-i-want-to-grant-synapse-admin-privileges")] admin: bool, }, + + /// Trigger a provisioning job for all users + ProvisionAllUsers, } impl Options { @@ -173,6 +178,31 @@ impl Options { Ok(()) } + + SC::ProvisionAllUsers => { + let _span = info_span!("cli.manage.provision_all_users").entered(); + let config: DatabaseConfig = root.load_config()?; + let pool = database_from_config(&config).await?; + let mut conn = pool.acquire().await?; + let mut repo = PgRepository::from_pool(&pool).await?.boxed(); + + // TODO: do some pagination here + let ids: Vec = sqlx::query_scalar("SELECT user_id FROM users") + .fetch_all(&mut conn) + .await?; + drop(conn); + + for id in ids { + let id = id.into(); + info!(user.id = %id, "Scheduling provisioning job"); + let job = ProvisionUserJob::new_for_id(id); + repo.job().schedule_job(job).await?; + } + + repo.save().await?; + + Ok(()) + } } } } diff --git a/crates/storage/src/job.rs b/crates/storage/src/job.rs index 754e4994..d42b2138 100644 --- a/crates/storage/src/job.rs +++ b/crates/storage/src/job.rs @@ -269,6 +269,15 @@ mod jobs { } } + #[doc(hidden)] + #[must_use] + pub fn new_for_id(user_id: Ulid) -> Self { + Self { + user_id, + set_display_name: None, + } + } + /// Set the display name of the user. #[must_use] pub fn set_display_name(mut self, display_name: String) -> Self {