From c4a12e235d92a4a26c92eed23616cb18e27a315b Mon Sep 17 00:00:00 2001 From: mdecimus Date: Wed, 1 May 2024 14:39:29 +0200 Subject: [PATCH] Master user implementation --- crates/common/src/config/jmap/settings.rs | 4 ++++ crates/common/src/lib.rs | 26 +++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/crates/common/src/config/jmap/settings.rs b/crates/common/src/config/jmap/settings.rs index 6e5a9864..284cb981 100644 --- a/crates/common/src/config/jmap/settings.rs +++ b/crates/common/src/config/jmap/settings.rs @@ -62,6 +62,7 @@ pub struct JmapConfig { pub oauth_expiry_refresh_token_renew: u64, pub oauth_max_auth_attempts: u32, pub fallback_admin: Option<(String, String)>, + pub fallback_admin_master: bool, pub spam_header: Option<(HeaderName<'static>, String)>, @@ -307,6 +308,9 @@ impl JmapConfig { .value("authentication.fallback-admin.secret") .map(|p| (u.to_string(), p.to_string())) }), + fallback_admin_master: config + .property_or_default("authentication.fallback-admin.enable-master", "false") + .unwrap_or(false), }; // Add capabilities diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs index 8ee47029..9973b396 100644 --- a/crates/common/src/lib.rs +++ b/crates/common/src/lib.rs @@ -221,10 +221,28 @@ impl Core { if let (Some((fallback_admin, fallback_pass)), Credentials::Plain { username, secret }) = (&self.jmap.fallback_admin, credentials) { - if username == fallback_admin && verify_secret_hash(fallback_pass, secret).await { - return Ok(AuthResult::Success(Principal::fallback_admin( - fallback_pass, - ))); + // Check master user + let (user_account, admin_account) = + match (self.jmap.fallback_admin_master, username.rsplit_once('%')) { + (true, Some((user_account, admin_account))) => { + (Some(user_account), admin_account) + } + _ => (None, username.as_str()), + }; + + if admin_account == fallback_admin && verify_secret_hash(fallback_pass, secret).await { + return Ok(if let Some(user_account) = user_account { + if let Some(principal) = directory + .query(QueryBy::Name(user_account), return_member_of) + .await? + { + AuthResult::Success(principal) + } else { + AuthResult::Failure + } + } else { + AuthResult::Success(Principal::fallback_admin(fallback_pass)) + }); } }