Files
inbuxa-server/crates/email/src/sieve/delete.rs
T
jcoffey-dev 5b963b06c6 Undelete: deleted files, calendar events, contacts and Sieve scripts are kept and restored where they were (UD-1, UD-8 to UD-11)
Files, events and contacts are noted when deleted for good and archived by
the unindex task when retention is on; Sieve scripts are archived at
deletion. A restore goes back to its folder, calendar or address book if it
still exists, takes a free " (restored)" name, comes back inactive for
scripts, and is refused over quota with the item left archived.
Acceptance tests 6, 8 and 12.
2026-09-18 21:07:27 -07:00

95 lines
3.0 KiB
Rust

/*
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use super::SieveScript;
use common::{Server, auth::AccessToken, storage::index::ObjectIndexBuilder};
use store::write::BatchBuilder;
use store::{
ValueKey,
write::{AlignedBytes, Archive},
};
use trc::AddContext;
use types::{collection::Collection, field::SieveField};
pub trait SieveScriptDelete: Sync + Send {
fn sieve_script_delete(
&self,
account_id: u32,
document_id: u32,
access_token: &AccessToken,
batch: &mut BatchBuilder,
) -> impl Future<Output = trc::Result<bool>> + Send;
}
impl SieveScriptDelete for Server {
async fn sieve_script_delete(
&self,
account_id: u32,
document_id: u32,
access_token: &AccessToken,
batch: &mut BatchBuilder,
) -> trc::Result<bool> {
// Fetch record
if let Some(obj_) = self
.store()
.get_value::<Archive<AlignedBytes>>(ValueKey::archive(
account_id,
Collection::SieveScript,
document_id,
))
.await?
{
// inbuxa: UD-1: a deleted script is kept, when archiving is on
if let Some(retention) =
inbuxa_features::undelete::settings::retention(self.registry())
.await?
.items
{
let script = obj_
.deserialize::<SieveScript>()
.caused_by(trc::location!())?;
let content = self
.blob_store()
.get_blob(script.blob_hash.as_slice(), 0..usize::MAX)
.await?
.map(|bytes| String::from_utf8_lossy(&bytes).into_owned())
.unwrap_or_default();
inbuxa_features::undelete::groupware::archive_sieve(
&self.core.storage.data,
self.registry(),
account_id,
&script.name,
content,
script.blob_hash.clone(),
retention,
)
.await?;
}
// Delete record
batch
.with_account_id(account_id)
.with_collection(Collection::SieveScript)
.with_document(document_id)
.clear(SieveField::Ids)
.custom(
ObjectIndexBuilder::<_, ()>::new()
.with_current(
obj_.to_unarchived::<SieveScript>()
.caused_by(trc::location!())?,
)
.with_changed_by(access_token.account_tenant_ids()),
)
.caused_by(trc::location!())?
.commit_point();
Ok(true)
} else {
Ok(false)
}
}
}