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.
95 lines
3.0 KiB
Rust
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)
|
|
}
|
|
}
|
|
}
|