fix(account): update "disabled" semantics

Modified the meaning of "disabled" accounts: they no longer connect to the IMAP server for syncing, but existing data remains accessible for search and queries.
This commit is contained in:
rustmailer
2025-11-24 22:34:40 +08:00
parent e41b26ba0b
commit 089b6885a7
6 changed files with 18 additions and 20 deletions
+8 -8
View File
@@ -112,7 +112,7 @@ impl AccountV1 {
}) })
} }
pub async fn check_account_active(account_id: u64) -> BichonResult<AccountModel> { pub async fn check_account_exists(account_id: u64) -> BichonResult<AccountModel> {
let account = let account =
secondary_find_impl::<AccountModel>(DB_MANAGER.meta_db(), AccountV1Key::id, account_id) secondary_find_impl::<AccountModel>(DB_MANAGER.meta_db(), AccountV1Key::id, account_id)
.await? .await?
@@ -123,12 +123,12 @@ impl AccountV1 {
) )
})?; })?;
if !account.enabled { // if !account.enabled {
return Err(raise_error!( // return Err(raise_error!(
format!("Account id='{account_id}' is disabled"), // format!("Account id='{account_id}' is disabled"),
ErrorCode::AccountDisabled // ErrorCode::AccountDisabled
)); // ));
} // }
Ok(account) Ok(account)
} }
@@ -277,7 +277,7 @@ impl AccountV1 {
let result = list_all_impl(DB_MANAGER.meta_db()) let result = list_all_impl(DB_MANAGER.meta_db())
.await? .await?
.into_iter() .into_iter()
.filter(|a: &AccountModel| a.enabled) //.filter(|a: &AccountModel| a.enabled)
.map(|account: AccountModel| MinimalAccount { .map(|account: AccountModel| MinimalAccount {
id: account.id, id: account.id,
email: account.email, email: account.email,
+1 -1
View File
@@ -27,7 +27,7 @@ use crate::raise_error;
use async_imap::types::Name; use async_imap::types::Name;
pub async fn get_account_mailboxes(account_id: u64, remote: bool) -> BichonResult<Vec<MailBox>> { pub async fn get_account_mailboxes(account_id: u64, remote: bool) -> BichonResult<Vec<MailBox>> {
let account = AccountModel::check_account_active(account_id).await?; let account = AccountModel::check_account_exists(account_id).await?;
if remote { if remote {
if matches!(account.account_type, AccountType::IMAP) { if matches!(account.account_type, AccountType::IMAP) {
request_imap_all_mailbox_list(account_id).await request_imap_all_mailbox_list(account_id).await
+1 -1
View File
@@ -68,7 +68,7 @@ pub async fn retrieve_email_content(
account_id: u64, account_id: u64,
id: u64, id: u64,
) -> BichonResult<FullMessageContent> { ) -> BichonResult<FullMessageContent> {
AccountModel::check_account_active(account_id).await?; AccountModel::check_account_exists(account_id).await?;
let eml = EML_INDEX_MANAGER let eml = EML_INDEX_MANAGER
.get(account_id, id) .get(account_id, id)
.await? .await?
+2 -2
View File
@@ -33,7 +33,7 @@ pub async fn list_messages_impl(
page: u64, page: u64,
page_size: u64, page_size: u64,
) -> BichonResult<DataPage<Envelope>> { ) -> BichonResult<DataPage<Envelope>> {
AccountModel::check_account_active(account_id).await?; AccountModel::check_account_exists(account_id).await?;
validate_pagination_params(page, page_size)?; validate_pagination_params(page, page_size)?;
ENVELOPE_INDEX_MANAGER ENVELOPE_INDEX_MANAGER
.list_mailbox_envelopes(account_id, mailbox_id, page, page_size, true) .list_mailbox_envelopes(account_id, mailbox_id, page, page_size, true)
@@ -62,7 +62,7 @@ pub async fn get_thread_messages(
page: u64, page: u64,
page_size: u64, page_size: u64,
) -> BichonResult<DataPage<Envelope>> { ) -> BichonResult<DataPage<Envelope>> {
AccountModel::check_account_active(account_id).await?; AccountModel::check_account_exists(account_id).await?;
ENVELOPE_INDEX_MANAGER ENVELOPE_INDEX_MANAGER
.list_thread_envelopes(account_id, thread_id, page, page_size, true) .list_thread_envelopes(account_id, thread_id, page, page_size, true)
.await .await
+3 -7
View File
@@ -16,14 +16,13 @@
// You should have received a copy of the GNU Affero General Public License // You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
use std::collections::BTreeSet; use std::collections::BTreeSet;
use crate::modules::account::migration::AccountModel;
use crate::modules::account::payload::{ use crate::modules::account::payload::{
filter_accessible_accounts, AccountCreateRequest, AccountUpdateRequest, MinimalAccount, filter_accessible_accounts, AccountCreateRequest, AccountUpdateRequest, MinimalAccount,
}; };
use crate::modules::account::state::AccountRunningState; use crate::modules::account::state::AccountRunningState;
use crate::modules::account::migration::AccountModel;
use crate::modules::common::auth::ClientContext; use crate::modules::common::auth::ClientContext;
use crate::modules::common::paginated::paginate_vec; use crate::modules::common::paginated::paginate_vec;
use crate::modules::error::code::ErrorCode; use crate::modules::error::code::ErrorCode;
@@ -114,11 +113,7 @@ impl AccountApi {
} }
/// List accounts with optional pagination parameters /// List accounts with optional pagination parameters
#[oai( #[oai(path = "/accounts", method = "get", operation_id = "list_accounts")]
path = "/accounts",
method = "get",
operation_id = "list_accounts"
)]
async fn list_accounts( async fn list_accounts(
&self, &self,
/// Optional. The page number to retrieve (starting from 1). /// Optional. The page number to retrieve (starting from 1).
@@ -172,6 +167,7 @@ impl AccountApi {
context: ClientContext, context: ClientContext,
) -> ApiResult<Json<AccountRunningState>> { ) -> ApiResult<Json<AccountRunningState>> {
let account_id = account_id.0; let account_id = account_id.0;
AccountModel::check_account_exists(account_id).await?;
context.require_account_access(account_id)?; context.require_account_access(account_id)?;
let state = AccountRunningState::get(account_id).await?.ok_or_else(|| { let state = AccountRunningState::get(account_id).await?.ok_or_else(|| {
raise_error!( raise_error!(
+3 -1
View File
@@ -16,7 +16,7 @@
// You should have received a copy of the GNU Affero General Public License // You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
use crate::modules::account::migration::AccountModel;
use crate::modules::common::auth::ClientContext; use crate::modules::common::auth::ClientContext;
use crate::modules::indexer::envelope::Envelope; use crate::modules::indexer::envelope::Envelope;
use crate::modules::indexer::manager::EML_INDEX_MANAGER; use crate::modules::indexer::manager::EML_INDEX_MANAGER;
@@ -156,6 +156,7 @@ impl MessageApi {
context: ClientContext, context: ClientContext,
) -> ApiResult<Attachment<Body>> { ) -> ApiResult<Attachment<Body>> {
let account_id = account_id.0; let account_id = account_id.0;
AccountModel::check_account_exists(account_id).await?;
context.require_account_access(account_id)?; context.require_account_access(account_id)?;
let id = id.0; let id = id.0;
let reader = EML_INDEX_MANAGER.get_reader(account_id, id).await?; let reader = EML_INDEX_MANAGER.get_reader(account_id, id).await?;
@@ -180,6 +181,7 @@ impl MessageApi {
context: ClientContext, context: ClientContext,
) -> ApiResult<Attachment<Body>> { ) -> ApiResult<Attachment<Body>> {
let account_id = account_id.0; let account_id = account_id.0;
AccountModel::check_account_exists(account_id).await?;
context.require_account_access(account_id)?; context.require_account_access(account_id)?;
let email_id = id.0; let email_id = id.0;
let name = name.0.trim(); let name = name.0.trim();