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_max_auth_attempts: u32,
pub fallback_admin: Option<(String, String)>,
pub fallback_admin_master: bool,
pub master_user: Option<(String, String)>,
pub spam_header: Option<(HeaderName<'static>, String)>,
@@ -321,9 +321,11 @@ 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),
master_user: config.value("authentication.master.user").and_then(|u| {
config
.value("authentication.master.secret")
.map(|p| (u.to_string(), p.to_string()))
}),
};
// Add capabilities

View File

@@ -240,33 +240,40 @@ impl Core {
Err(err) => Err(err),
};
// Then check if the credentials match the fallback admin
if let (Some((fallback_admin, fallback_pass)), Credentials::Plain { username, secret }) =
(&self.jmap.fallback_admin, credentials)
{
// 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))
});
// Then check if the credentials match the fallback admin or master user
match (
&self.jmap.fallback_admin,
&self.jmap.master_user,
credentials,
) {
(Some((fallback_admin, fallback_pass)), _, Credentials::Plain { username, secret })
if username == fallback_admin =>
{
if verify_secret_hash(fallback_pass, secret).await {
return Ok(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 {

View File

@@ -396,6 +396,14 @@ impl JMAP {
return Ok(());
}
tracing::debug!(
event = "info",
context = "email_auto_expunge",
account_id = account_id,
count = destroy_ids.len(),
"Auto-expunging messages."
);
// Tombstone messages
let (changes, _) = self.emails_tombstone(account_id, destroy_ids).await?;
@@ -436,6 +444,14 @@ impl JMAP {
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
self.core
.storage