Journaling: capture at the queue, the built-in journal, retention
Phase 2 of the journaling spec. - A copy of each message is taken in MessageWrapper::queue, after DLP and transport rules, for every enabled journal that takes it (direction and scope: everyone, or accounts, groups, domains, tenants). If the copy can't be taken the message isn't queued (temporary failure). - The journal report: the envelope one field a line (sender, To, Cc, Bcc from the envelope, list members from their ORCPT, direction, held for review), then the queued message byte for byte as message/rfc822. - The built-in journal under J in the inbuxa subspace: one chain per node whose links name each entry by SHA-256, so entries can expire out of chain order; purge leaves a marker, and verify catches an entry changed or removed early and a report that doesn't match. - Retention per journal (30 to 3650 days); an entry keeps what it was written with. The daily maintenance purges what's due, keeping entries whose people a legal hold covers (deleted accounts a hold keeps too), and records the counts in the audit log. - inbuxa:Journal get/set, audited by the request layer. Permissions 680-683: administrators see and change journals; the Compliance Officer sees, searches and exports. Whoever changes journals may grant search and export without holding them, so officers can still be appointed. - Catalog entries (inbuxa:Journal, source "journal"); spec as-built notes. tests/src/system/journal.rs: validation, internal mail with a Bcc, outgoing into two journals, incoming over LMTP, the report and its original, tamper and early removal caught, hold-aware purge, retention changes leave entries alone, disabled and removed journals take nothing.
This commit is contained in:
@@ -112,6 +112,7 @@ pub enum GetResponseMethod {
|
||||
AccountLock(GetResponse<crate::object::inbuxa_account_lock::AccountLock>),
|
||||
LegalHold(GetResponse<crate::object::inbuxa_legal_hold::LegalHold>),
|
||||
MailRule(GetResponse<crate::object::inbuxa_mail_rule::MailRule>),
|
||||
Journal(GetResponse<crate::object::inbuxa_journal::Journal>),
|
||||
HeldMessage(GetResponse<crate::object::inbuxa_held_message::HeldMessage>),
|
||||
HoldExport(GetResponse<crate::object::inbuxa_hold_export::HoldExport>),
|
||||
ProtocolPolicy(GetResponse<crate::object::inbuxa_protocol_policy::ProtocolPolicy>),
|
||||
@@ -150,6 +151,7 @@ pub enum SetResponseMethod {
|
||||
AccountLock(Box<SetResponse<crate::object::inbuxa_account_lock::AccountLock>>),
|
||||
LegalHold(Box<SetResponse<crate::object::inbuxa_legal_hold::LegalHold>>),
|
||||
MailRule(Box<SetResponse<crate::object::inbuxa_mail_rule::MailRule>>),
|
||||
Journal(Box<SetResponse<crate::object::inbuxa_journal::Journal>>),
|
||||
HeldMessage(Box<SetResponse<crate::object::inbuxa_held_message::HeldMessage>>),
|
||||
HoldExport(Box<SetResponse<crate::object::inbuxa_hold_export::HoldExport>>),
|
||||
Explanation(Box<SetResponse<crate::object::inbuxa_explanation::Explanation>>),
|
||||
@@ -841,6 +843,19 @@ impl<'x> From<SetResponse<crate::object::inbuxa_mail_rule::MailRule>> for Respon
|
||||
}
|
||||
}
|
||||
|
||||
// inbuxa: journaling
|
||||
impl<'x> From<GetResponse<crate::object::inbuxa_journal::Journal>> for ResponseMethod<'x> {
|
||||
fn from(value: GetResponse<crate::object::inbuxa_journal::Journal>) -> Self {
|
||||
ResponseMethod::Get(GetResponseMethod::Journal(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'x> From<SetResponse<crate::object::inbuxa_journal::Journal>> for ResponseMethod<'x> {
|
||||
fn from(value: SetResponse<crate::object::inbuxa_journal::Journal>) -> Self {
|
||||
ResponseMethod::Set(SetResponseMethod::Journal(Box::new(value)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'x> From<GetResponse<crate::object::inbuxa_legal_hold::LegalHold>> for ResponseMethod<'x> {
|
||||
fn from(value: GetResponse<crate::object::inbuxa_legal_hold::LegalHold>) -> Self {
|
||||
ResponseMethod::Get(GetResponseMethod::LegalHold(value))
|
||||
|
||||
Reference in New Issue
Block a user