Jul 20 - Update codes to comply with some framework (SOC 2 TYPE 2, ISO, etc)
This commit is contained in:
+17
-8
@@ -96,24 +96,29 @@ def view(log_id):
|
||||
|
||||
# ── Purge old logs ────────────────────────────────────────────────────────────
|
||||
|
||||
# Minimum floor of 1 year is deliberate: audit trails are the primary control
|
||||
# evidence for SOC 2 / ISO 27001 access-monitoring, so shorter windows (the old
|
||||
# 7/30/60/90/180-day options) are no longer offered — a purge can only ever
|
||||
# remove entries old enough that they're outside any plausible audit lookback.
|
||||
PURGE_OPTIONS = {
|
||||
7: '7 days',
|
||||
30: '30 days',
|
||||
60: '60 days',
|
||||
90: '90 days',
|
||||
180: '180 days',
|
||||
365: '1 year',
|
||||
730: '2 years',
|
||||
}
|
||||
|
||||
PURGE_CONFIRM_PHRASE = 'PURGE'
|
||||
|
||||
@bp.route('/purge', methods=['POST'])
|
||||
@login_required
|
||||
@admin_required
|
||||
def purge():
|
||||
"""Delete audit log entries older than the selected threshold.
|
||||
|
||||
Accepts a POST form field `older_than` (integer days).
|
||||
The purge itself is recorded as a new audit log entry so there is
|
||||
always a traceable record of who purged what and when.
|
||||
Accepts POST form fields `older_than` (integer days, >= 1 year) and
|
||||
`confirm_phrase` (must exactly equal PURGE_CONFIRM_PHRASE) — the typed
|
||||
confirmation is extra friction against an accidental click on an
|
||||
otherwise-irreversible action. The purge itself is recorded as a new
|
||||
audit log entry so there is always a traceable record of who purged
|
||||
what and when.
|
||||
"""
|
||||
try:
|
||||
older_than = int(request.form.get('older_than', 0))
|
||||
@@ -124,6 +129,10 @@ def purge():
|
||||
flash('Invalid purge threshold selected.', 'danger')
|
||||
return redirect(url_for('audit.index'))
|
||||
|
||||
if request.form.get('confirm_phrase', '').strip() != PURGE_CONFIRM_PHRASE:
|
||||
flash(f'You must type "{PURGE_CONFIRM_PHRASE}" to confirm this action.', 'danger')
|
||||
return redirect(url_for('audit.index'))
|
||||
|
||||
cutoff = now_eastern() - timedelta(days=older_than)
|
||||
deleted = AuditLog.query.filter(AuditLog.created_at < cutoff).delete()
|
||||
db.session.flush()
|
||||
|
||||
Reference in New Issue
Block a user