1
0
Fork 0

Add support for auto-deleting trashed items

Upstream will soon auto-delete trashed items after 30 days, but some people
use the trash as an archive folder, so to avoid unexpected data loss, this
implementation requires the user to explicitly enable auto-deletion.
Dieser Commit ist enthalten in:
Jeremy Lin 2021-04-02 20:52:15 -07:00
Ursprung 73ff8d79f7
Commit d77333576b
7 geänderte Dateien mit 54 neuen und 2 gelöschten Zeilen

Datei anzeigen

@ -68,6 +68,10 @@
## Cron schedule of the job that checks for Sends past their deletion date. ## Cron schedule of the job that checks for Sends past their deletion date.
## Defaults to hourly. Set blank to disable this job. ## Defaults to hourly. Set blank to disable this job.
# SEND_PURGE_SCHEDULE="0 0 * * * *" # SEND_PURGE_SCHEDULE="0 0 * * * *"
##
## Cron schedule of the job that checks for trashed items to delete permanently.
## Defaults to daily. Set blank to disable this job.
# TRASH_PURGE_SCHEDULE="0 0 0 * * *"
## Enable extended logging, which shows timestamps and targets in the logs ## Enable extended logging, which shows timestamps and targets in the logs
# EXTENDED_LOGGING=true # EXTENDED_LOGGING=true

Datei anzeigen

@ -13,7 +13,7 @@ use crate::{
api::{self, EmptyResult, JsonResult, JsonUpcase, Notify, PasswordData, UpdateType}, api::{self, EmptyResult, JsonResult, JsonUpcase, Notify, PasswordData, UpdateType},
auth::Headers, auth::Headers,
crypto, crypto,
db::{models::*, DbConn}, db::{models::*, DbConn, DbPool},
CONFIG, CONFIG,
}; };
@ -77,6 +77,15 @@ pub fn routes() -> Vec<Route> {
] ]
} }
pub fn purge_trashed_ciphers(pool: DbPool) {
debug!("Purging trashed ciphers");
if let Ok(conn) = pool.get() {
Cipher::purge_trash(&conn);
} else {
error!("Failed to get DB connection while purging trashed ciphers")
}
}
#[derive(FromForm, Default)] #[derive(FromForm, Default)]
struct SyncData { struct SyncData {
#[form(field = "excludeDomains")] #[form(field = "excludeDomains")]

Datei anzeigen

@ -5,6 +5,7 @@ mod organizations;
pub mod two_factor; pub mod two_factor;
mod sends; mod sends;
pub use ciphers::purge_trashed_ciphers;
pub use sends::purge_sends; pub use sends::purge_sends;
pub fn routes() -> Vec<Route> { pub fn routes() -> Vec<Route> {

Datei anzeigen

@ -11,6 +11,7 @@ use serde_json::Value;
pub use crate::api::{ pub use crate::api::{
admin::routes as admin_routes, admin::routes as admin_routes,
core::purge_sends, core::purge_sends,
core::purge_trashed_ciphers,
core::routes as core_routes, core::routes as core_routes,
icons::routes as icons_routes, icons::routes as icons_routes,
identity::routes as identity_routes, identity::routes as identity_routes,

Datei anzeigen

@ -323,6 +323,9 @@ make_config! {
/// Send purge schedule |> Cron schedule of the job that checks for Sends past their deletion date. /// Send purge schedule |> Cron schedule of the job that checks for Sends past their deletion date.
/// Defaults to hourly. Set blank to disable this job. /// Defaults to hourly. Set blank to disable this job.
send_purge_schedule: String, false, def, "0 0 * * * *".to_string(); send_purge_schedule: String, false, def, "0 0 * * * *".to_string();
/// Trash purge schedule |> Cron schedule of the job that checks for trashed items to delete permanently.
/// Defaults to daily. Set blank to disable this job.
trash_purge_schedule: String, false, def, "0 0 0 * * *".to_string();
}, },
/// General settings /// General settings
@ -347,6 +350,11 @@ make_config! {
/// Per-organization attachment limit (KB) |> Limit in kilobytes for an organization attachments, once the limit is exceeded it won't be possible to upload more /// Per-organization attachment limit (KB) |> Limit in kilobytes for an organization attachments, once the limit is exceeded it won't be possible to upload more
org_attachment_limit: i64, true, option; org_attachment_limit: i64, true, option;
/// Trash auto-delete days |> Number of days to wait before auto-deleting a trashed item.
/// If unset, trashed items are not auto-deleted. This setting applies globally, so make
/// sure to inform all users of any changes to this setting.
trash_auto_delete_days: i64, true, option;
/// Disable icon downloads |> Set to true to disable icon downloading, this would still serve icons from /// Disable icon downloads |> Set to true to disable icon downloading, this would still serve icons from
/// $ICON_CACHE_FOLDER, but it won't produce any external network request. Needs to set $ICON_CACHE_TTL to 0, /// $ICON_CACHE_FOLDER, but it won't produce any external network request. Needs to set $ICON_CACHE_TTL to 0,
/// otherwise it will delete them and they won't be downloaded again. /// otherwise it will delete them and they won't be downloaded again.

Datei anzeigen

@ -1,6 +1,8 @@
use chrono::{NaiveDateTime, Utc}; use chrono::{Duration, NaiveDateTime, Utc};
use serde_json::Value; use serde_json::Value;
use crate::CONFIG;
use super::{ use super::{
Attachment, Attachment,
CollectionCipher, CollectionCipher,
@ -271,6 +273,17 @@ impl Cipher {
Ok(()) Ok(())
} }
/// Purge all ciphers that are old enough to be auto-deleted.
pub fn purge_trash(conn: &DbConn) {
if let Some(auto_delete_days) = CONFIG.trash_auto_delete_days() {
let now = Utc::now().naive_utc();
let dt = now - Duration::days(auto_delete_days);
for cipher in Self::find_deleted_before(&dt, conn) {
cipher.delete(&conn).ok();
}
}
}
pub fn move_to_folder(&self, folder_uuid: Option<String>, user_uuid: &str, conn: &DbConn) -> EmptyResult { pub fn move_to_folder(&self, folder_uuid: Option<String>, user_uuid: &str, conn: &DbConn) -> EmptyResult {
User::update_uuid_revision(user_uuid, conn); User::update_uuid_revision(user_uuid, conn);
@ -511,6 +524,15 @@ impl Cipher {
}} }}
} }
/// Find all ciphers that were deleted before the specified datetime.
pub fn find_deleted_before(dt: &NaiveDateTime, conn: &DbConn) -> Vec<Self> {
db_run! {conn: {
ciphers::table
.filter(ciphers::deleted_at.lt(dt))
.load::<CipherDb>(conn).expect("Error loading ciphers").from_db()
}}
}
pub fn get_collections(&self, user_id: &str, conn: &DbConn) -> Vec<String> { pub fn get_collections(&self, user_id: &str, conn: &DbConn) -> Vec<String> {
db_run! {conn: { db_run! {conn: {
ciphers_collections::table ciphers_collections::table

Datei anzeigen

@ -354,6 +354,13 @@ fn schedule_jobs(pool: db::DbPool) {
})); }));
} }
// Purge trashed items that are old enough to be auto-deleted.
if !CONFIG.trash_purge_schedule().is_empty() {
sched.add(Job::new(CONFIG.trash_purge_schedule().parse().unwrap(), || {
api::purge_trashed_ciphers(pool.clone());
}));
}
// Periodically check for jobs to run. We probably won't need any // Periodically check for jobs to run. We probably won't need any
// jobs that run more often than once a minute, so a default poll // jobs that run more often than once a minute, so a default poll
// interval of 30 seconds should be sufficient. Users who want to // interval of 30 seconds should be sufficient. Users who want to