Legal holds, step 1: the hold itself

inbuxa:LegalHold get/set places a hold on accounts, groups, domains,
tenants or the whole server, with an optional date range. A hold's range
and scope can only widen, a released hold is read-only, and none is ever
deleted. Placing, changing and releasing each need a reason and are
audited (LH-1, LH-3, LH-10, AU-12).

Permissions 669-672 (see, place, widen or release, export held data)
go to server administrators only; the tenant ceiling always strips them,
as it does Impersonate (LH-13). Schema: Compliance > Legal Holds.

What a hold keeps comes next, through the undelete hooks.

Also moves the lock expiry helpers below the lock module's imports.
This commit is contained in:
2026-09-27 19:33:06 -07:00
parent 621ebdff74
commit 5d2e35b2dc
24 changed files with 1502 additions and 10 deletions
+5 -5
View File
@@ -27,6 +27,11 @@ use store::{
write::{AnyClass, BatchBuilder, ValueClass},
};
use trc::AddContext;
use types::{
acl::{Acl, AclGrant},
collection::Collection,
};
use utils::map::bitmap::Bitmap;
/// Rung when a lock is written, so this node's expiry timer re-reads the
/// `until` dates (AL-5): a delegation ends at its time, not at a sweep.
@@ -53,11 +58,6 @@ pub fn ended_between(locks: &[Lock], after: u64, now: u64) -> impl Iterator<Item
})
.map(|lock| lock.account_id)
}
use types::{
acl::{Acl, AclGrant},
collection::Collection,
};
use utils::map::bitmap::Bitmap;
const FEATURE: u8 = b'K';
const KIND_LOCK: u8 = b'l';