Use separate account for master user
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user