Use separate account for master user

This commit is contained in:
mdecimus
2024-05-19 16:09:52 +02:00
parent 66cc0a3072
commit bd4a2f5956
3 changed files with 55 additions and 30 deletions

View File

@@ -65,7 +65,7 @@ pub struct JmapConfig {
pub oauth_expiry_refresh_token_renew: u64, pub oauth_expiry_refresh_token_renew: u64,
pub oauth_max_auth_attempts: u32, pub oauth_max_auth_attempts: u32,
pub fallback_admin: Option<(String, String)>, pub fallback_admin: Option<(String, String)>,
pub fallback_admin_master: bool, pub master_user: Option<(String, String)>,
pub spam_header: Option<(HeaderName<'static>, String)>, pub spam_header: Option<(HeaderName<'static>, String)>,
@@ -321,9 +321,11 @@ impl JmapConfig {
.value("authentication.fallback-admin.secret") .value("authentication.fallback-admin.secret")
.map(|p| (u.to_string(), p.to_string())) .map(|p| (u.to_string(), p.to_string()))
}), }),
fallback_admin_master: config master_user: config.value("authentication.master.user").and_then(|u| {
.property_or_default("authentication.fallback-admin.enable-master", "false") config
.unwrap_or(false), .value("authentication.master.secret")
.map(|p| (u.to_string(), p.to_string()))
}),
}; };
// Add capabilities // Add capabilities

View File

@@ -240,33 +240,40 @@ impl Core {
Err(err) => Err(err), Err(err) => Err(err),
}; };
// Then check if the credentials match the fallback admin // Then check if the credentials match the fallback admin or master user
if let (Some((fallback_admin, fallback_pass)), Credentials::Plain { username, secret }) = match (
(&self.jmap.fallback_admin, credentials) &self.jmap.fallback_admin,
{ &self.jmap.master_user,
// Check master user credentials,
let (user_account, admin_account) = ) {
match (self.jmap.fallback_admin_master, username.rsplit_once('%')) { (Some((fallback_admin, fallback_pass)), _, Credentials::Plain { username, secret })
(true, Some((user_account, admin_account))) => { if username == fallback_admin =>
(Some(user_account), admin_account) {
} if verify_secret_hash(fallback_pass, secret).await {
_ => (None, username.as_str()), return Ok(AuthResult::Success(Principal::fallback_admin(
}; fallback_pass,
)));
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))
});
} }
(_, Some((master_user, master_pass)), Credentials::Plain { username, secret })
if username.ends_with(master_user) =>
{
if verify_secret_hash(master_pass, secret).await {
let username = username.strip_suffix(master_user).unwrap();
let username = username.strip_suffix('%').unwrap_or(username);
return Ok(
if let Some(principal) = directory
.query(QueryBy::Name(username), return_member_of)
.await?
{
AuthResult::Success(principal)
} else {
AuthResult::Failure
},
);
}
}
_ => {}
} }
if let Err(err) = result { if let Err(err) = result {

View File

@@ -396,6 +396,14 @@ impl JMAP {
return Ok(()); return Ok(());
} }
tracing::debug!(
event = "info",
context = "email_auto_expunge",
account_id = account_id,
count = destroy_ids.len(),
"Auto-expunging messages."
);
// Tombstone messages // Tombstone messages
let (changes, _) = self.emails_tombstone(account_id, destroy_ids).await?; let (changes, _) = self.emails_tombstone(account_id, destroy_ids).await?;
@@ -436,6 +444,14 @@ impl JMAP {
return Ok(()); return Ok(());
} }
tracing::debug!(
event = "info",
context = "email_purge_tombstoned",
account_id = account_id,
count = tombstoned_ids.len(),
"Purging tombstoned messages."
);
// Delete full-text index // Delete full-text index
self.core self.core
.storage .storage