Add syn2mas flag to ignore missing auth providers
Currently `syn2mas` will always error in the Synapse checks phase if it finds auth providers in the `user_external_ids` database table, that are not configured in Synapse config. While normally this the right thing to do, we may have situations where we know what we're doing, and want to ignore invalid looking data in the external identifiers table. If the flag is given, ignore errors and output them as warnings instead.
This commit is contained in:
@@ -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?;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user