Add syn2mas flag to ignore missing auth providers (#5451)

This commit is contained in:
Quentin Gliech
2026-01-29 11:23:17 +01:00
committed by GitHub
3 changed files with 49 additions and 8 deletions

View File

@@ -61,6 +61,14 @@ pub(super) struct Options {
/// configure all values through those environment variables.
#[clap(long = "synapse-database-uri", global = true)]
synapse_database_uri: Option<PgConnectOptions>,
/// Make missing auth providers in Synapse config warnings instead of
/// errors. If this flag is set, and we find `auth_provider` values in
/// the Synapse `user_external_ids` table, that are not configured in
/// the Synapse OIDC configuration, instead of erroring we will just
/// output warnings.
#[clap(long = "ignore-missing-auth-providers", global = true)]
ignore_missing_auth_providers: bool,
}
#[derive(Parser, Debug)]
@@ -169,8 +177,13 @@ impl Options {
// Check databases
syn2mas::mas_pre_migration_checks(&mut mas_connection).await?;
{
let (extra_warnings, extra_errors) =
syn2mas::synapse_database_check(&mut syn_conn, &synapse_config, figment).await?;
let (extra_warnings, extra_errors) = syn2mas::synapse_database_check(
&mut syn_conn,
&synapse_config,
figment,
self.ignore_missing_auth_providers,
)
.await?;
check_warnings.extend(extra_warnings);
check_errors.extend(extra_errors);
}
@@ -261,6 +274,7 @@ impl Options {
&mut rng,
provider_id_mappings,
&progress,
self.ignore_missing_auth_providers,
)
.await?;

View File

@@ -141,6 +141,7 @@ struct MigrationState {
/// - An underlying database access error, either to MAS or to Synapse.
/// - Invalid data in the Synapse database.
#[expect(clippy::implicit_hasher)]
#[allow(clippy::too_many_arguments)]
pub async fn migrate(
mut synapse: SynapseReader<'_>,
mas: MasWriter,
@@ -149,6 +150,7 @@ pub async fn migrate(
rng: &mut impl RngCore,
provider_id_mapping: std::collections::HashMap<String, Uuid>,
progress: &Progress,
ignore_missing_auth_providers: bool,
) -> Result<(), Error> {
let counts = synapse.count_rows().await.into_synapse("counting users")?;
@@ -171,8 +173,15 @@ pub async fn migrate(
let (mas, state) = migrate_threepids(&mut synapse, mas, rng, state, progress_counter).await?;
let progress_counter = progress.migrating_data(EntityType::ExternalIds, counts.external_ids);
let (mas, state) =
migrate_external_ids(&mut synapse, mas, rng, state, progress_counter).await?;
let (mas, state) = migrate_external_ids(
&mut synapse,
mas,
rng,
state,
progress_counter,
ignore_missing_auth_providers,
)
.await?;
let progress_counter = progress.migrating_data(
EntityType::NonRefreshableAccessTokens,
@@ -452,6 +461,7 @@ async fn migrate_external_ids(
rng: &mut impl RngCore,
state: MigrationState,
progress_counter: ProgressCounter,
ignore_missing_auth_providers: bool,
) -> Result<(MasWriter, MigrationState), Error> {
let start = Instant::now();
let progress_counter_ = progress_counter.clone();
@@ -489,6 +499,10 @@ async fn migrate_external_ids(
let Some(&upstream_provider_id) = state.provider_id_mapping.get(&auth_provider)
else {
if ignore_missing_auth_providers {
progress_counter.increment_skipped();
continue;
}
return Err(Error::MissingAuthProviderMapping {
synapse_id: auth_provider,
user: synapse_user_id,

View File

@@ -130,6 +130,11 @@ pub enum CheckWarning {
"Synapse database contains {num_non_email_3pids} non-email 3PIDs (probably phone numbers), which will be migrated but are not supported by MAS."
)]
NonEmailThreepidsInDatabase { num_non_email_3pids: i64 },
#[error(
"Synapse database contains {num_users} users associated to the OpenID Connect or OAuth2 provider '{provider}' but the Synapse configuration does not contain this provider."
)]
SynapseMissingOAuthProvider { provider: String, num_users: i64 },
}
/// Check that the Synapse configuration is sane for migration.
@@ -257,6 +262,7 @@ pub async fn synapse_database_check(
synapse_connection: &mut PgConnection,
synapse: &Config,
mas: &Figment,
ignore_missing_auth_providers: bool,
) -> Result<(Vec<CheckWarning>, Vec<CheckError>), Error> {
#[derive(FromRow)]
struct UpstreamOAuthProvider {
@@ -309,10 +315,17 @@ pub async fn synapse_database_check(
let matching_syn = syn_oauth2.get(&row.auth_provider);
let Some(matching_syn) = matching_syn else {
errors.push(CheckError::SynapseMissingOAuthProvider {
provider: row.auth_provider,
num_users: row.num_users,
});
if ignore_missing_auth_providers {
warnings.push(CheckWarning::SynapseMissingOAuthProvider {
provider: row.auth_provider,
num_users: row.num_users,
});
} else {
errors.push(CheckError::SynapseMissingOAuthProvider {
provider: row.auth_provider,
num_users: row.num_users,
});
}
continue;
};