feat(oidc): permit auto/manual oidc account link/unlink

link are checking that email matches, +email alias are normalize into email
if email is already used on another account, link is not possible
not usurpation risk as the IDP is choosen by the admin
This commit is contained in:
Edouard Vanbelle
2026-08-08 17:19:05 +02:00
parent d8b3f2e026
commit e9495a63ad
20 changed files with 1791 additions and 135 deletions
+16
View File
@@ -1628,6 +1628,15 @@ pub struct OidcConfig {
pub disable_password_login: bool,
/// OIDC provider display name (shown in UI)
pub provider_name: String,
/// When TRUE (default), an OIDC login whose subject doesn't match
/// any existing user AUTO-LINKS to the local user with the same
/// verified email address (if any). Requires `email_verified=true`
/// from the IdP. See docs/plan/oidc-account-linking.md § Auto-link.
///
/// Set FALSE for compliance postures that require explicit consent
/// for every OIDC linkage. Self-service link flow still works
/// regardless of this flag.
pub auto_link_email_match: bool,
}
impl Default for OidcConfig {
@@ -1644,6 +1653,7 @@ impl Default for OidcConfig {
admin_groups: String::new(),
disable_password_login: false,
provider_name: "SSO".to_string(),
auto_link_email_match: true,
}
}
}
@@ -1852,6 +1862,9 @@ impl OidcConfig {
if let Ok(v) = env::var("OXICLOUD_OIDC_AUTO_PROVISION") {
cfg.auto_provision = v.parse::<bool>().unwrap_or(true);
}
if let Ok(v) = env::var("OXICLOUD_OIDC_AUTO_LINK_EMAIL_MATCH") {
cfg.auto_link_email_match = v.parse::<bool>().unwrap_or(true);
}
if let Ok(v) = env::var("OXICLOUD_OIDC_ADMIN_GROUPS") {
cfg.admin_groups = v;
}
@@ -3432,6 +3445,9 @@ impl AppConfig {
if let Ok(v) = env::var("OXICLOUD_OIDC_AUTO_PROVISION") {
config.oidc.auto_provision = v.parse::<bool>().unwrap_or(true);
}
if let Ok(v) = env::var("OXICLOUD_OIDC_AUTO_LINK_EMAIL_MATCH") {
config.oidc.auto_link_email_match = v.parse::<bool>().unwrap_or(true);
}
if let Ok(v) = env::var("OXICLOUD_OIDC_ADMIN_GROUPS") {
config.oidc.admin_groups = v;
}