Change: default-enable audit log

This commit is contained in:
shamoon 2024-04-01 14:51:51 -07:00
parent 00b04c2e86
commit 57709591f3
11 changed files with 57 additions and 30 deletions

View File

@ -1309,13 +1309,11 @@ assigns or creates tags if a properly formatted barcode is detected.
## Audit Trail
#### [`PAPERLESS_AUDIT_LOG_ENABLED=<bool>`](#PAPERLESS_AUDIT_LOG_ENABLED) {#PAPERLESS_AUDIT_LOG_ENABLED}
#### [`PAPERLESS_AUDIT_LOG_DISABLED=<bool>`](#PAPERLESS_AUDIT_LOG_DISABLED) {#PAPERLESS_AUDIT_LOG_DISABLED}
: Enables an audit trail for documents, document types, correspondents, and tags. Log entries can be viewed in the Django backend only.
: Disables the audit trail for documents, document types, correspondents, and tags.
!!! warning
Once enabled cannot be disabled
Defaults to false.
## Collate Double-Sided Documents {#collate}

View File

@ -15,7 +15,7 @@ from documents.models import ShareLink
from documents.models import StoragePath
from documents.models import Tag
if settings.AUDIT_LOG_ENABLED:
if not settings.AUDIT_LOG_DISABLED:
from auditlog.admin import LogEntryAdmin
from auditlog.models import LogEntry
@ -197,7 +197,7 @@ admin.site.register(ShareLink, ShareLinksAdmin)
admin.site.register(CustomField, CustomFieldsAdmin)
admin.site.register(CustomFieldInstance, CustomFieldInstancesAdmin)
if settings.AUDIT_LOG_ENABLED:
if not settings.AUDIT_LOG_DISABLED:
class LogEntryAUDIT(LogEntryAdmin):
def has_delete_permission(self, request, obj=None):

View File

@ -9,6 +9,9 @@ from typing import Optional
import tqdm
from django.conf import settings
if not settings.AUDIT_LOG_DISABLED:
from auditlog.models import LogEntry
from django.contrib.auth.models import Group
from django.contrib.auth.models import Permission
from django.contrib.auth.models import User
@ -307,6 +310,11 @@ class Command(BaseCommand):
serializers.serialize("json", ApplicationConfiguration.objects.all()),
)
if not settings.AUDIT_LOG_DISABLED:
manifest += json.loads(
serializers.serialize("json", LogEntry.objects.all()),
)
# These are treated specially and included in the per-document manifest
# if that setting is enabled. Otherwise, they are just exported to the bulk
# manifest

View File

@ -20,7 +20,7 @@ from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from multiselectfield import MultiSelectField
if settings.AUDIT_LOG_ENABLED:
if not settings.AUDIT_LOG_DISABLED:
from auditlog.registry import auditlog
from documents.data_models import DocumentSource
@ -881,7 +881,7 @@ class CustomFieldInstance(models.Model):
raise NotImplementedError(self.field.data_type)
if settings.AUDIT_LOG_ENABLED:
if not settings.AUDIT_LOG_DISABLED:
auditlog.register(Document, m2m_fields={"tags"})
auditlog.register(Correspondent)
auditlog.register(Tag)

View File

@ -43,7 +43,7 @@ from documents.plugins.helpers import ProgressStatusOptions
from documents.sanity_checker import SanityCheckFailedException
from documents.signals import document_updated
if settings.AUDIT_LOG_ENABLED:
if not settings.AUDIT_LOG_DISABLED:
import json
from auditlog.models import LogEntry
@ -275,7 +275,7 @@ def update_document_archive_file(document_id):
archive_filename=document.archive_filename,
)
newDocument = Document.objects.get(pk=document.pk)
if settings.AUDIT_LOG_ENABLED:
if not settings.AUDIT_LOG_DISABLED:
LogEntry.objects.log_create(
instance=oldDocument,
changes=json.dumps(

View File

@ -7,6 +7,7 @@ from pathlib import Path
from unittest import mock
from zipfile import ZipFile
from auditlog.models import LogEntry
from django.contrib.auth.models import Group
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
@ -122,6 +123,19 @@ class TestExportImport(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
self.workflow.actions.add(self.action)
self.workflow.save()
LogEntry.objects.log_create(
instance=self.dt1,
changes=json.dumps(
{
"name": [
self.dt1.name,
"New name",
],
},
),
action=LogEntry.Action.UPDATE,
)
super().setUp()
def _get_document_from_manifest(self, manifest, id):
@ -780,3 +794,17 @@ class TestExportImport(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
self.assertEqual(ContentType.objects.count(), num_content_type_objects)
self.assertEqual(Permission.objects.count(), num_permission_objects + 1)
def test_exporter_with_auditlog_disabled(self):
shutil.rmtree(os.path.join(self.dirs.media_dir, "documents"))
shutil.copytree(
os.path.join(os.path.dirname(__file__), "samples", "documents"),
os.path.join(self.dirs.media_dir, "documents"),
)
with override_settings(
AUDIT_LOG_DISABLED=True,
):
manifest = self._do_export(use_filename_format=True)
for obj in manifest:
self.assertNotEqual(obj["model"], "auditlog.logentry")

View File

@ -153,7 +153,7 @@ from paperless.config import GeneralConfig
from paperless.db import GnuPG
from paperless.views import StandardPagination
if settings.AUDIT_LOG_ENABLED:
if not settings.AUDIT_LOG_DISABLED:
from auditlog.models import LogEntry
logger = logging.getLogger("paperless.api")
@ -636,7 +636,7 @@ class DocumentViewSet(
c.save()
# If audit log is enabled make an entry in the log
# about this note change
if settings.AUDIT_LOG_ENABLED:
if not settings.AUDIT_LOG_DISABLED:
LogEntry.objects.log_create(
instance=doc,
changes=json.dumps(
@ -671,7 +671,7 @@ class DocumentViewSet(
return HttpResponseForbidden("Insufficient permissions to delete notes")
note = Note.objects.get(id=int(request.GET.get("id")))
if settings.AUDIT_LOG_ENABLED:
if not settings.AUDIT_LOG_DISABLED:
LogEntry.objects.log_create(
instance=doc,
changes=json.dumps(

View File

@ -5,7 +5,6 @@ import shutil
import stat
from django.conf import settings
from django.core.checks import Critical
from django.core.checks import Error
from django.core.checks import Warning
from django.core.checks import register
@ -205,13 +204,10 @@ def audit_log_check(app_configs, **kwargs):
all_tables = db_conn.introspection.table_names()
result = []
if ("auditlog_logentry" in all_tables) and not (settings.AUDIT_LOG_ENABLED):
if ("auditlog_logentry" in all_tables) or (settings.AUDIT_LOG_DISABLED):
result.append(
Critical(
(
"auditlog table was found but PAPERLESS_AUDIT_LOG_ENABLED"
" is not active. This setting cannot be disabled after enabling"
),
Warning(
("auditlog table was found but AUDIT_LOG_DISABLED is active."),
),
)

View File

@ -1045,8 +1045,8 @@ TIKA_GOTENBERG_ENDPOINT = os.getenv(
if TIKA_ENABLED:
INSTALLED_APPS.append("paperless_tika.apps.PaperlessTikaConfig")
AUDIT_LOG_ENABLED = __get_boolean("PAPERLESS_AUDIT_LOG_ENABLED", "NO")
if AUDIT_LOG_ENABLED:
AUDIT_LOG_DISABLED = __get_boolean("PAPERLESS_AUDIT_LOG_DISABLED", "NO")
if not AUDIT_LOG_DISABLED:
INSTALLED_APPS.append("auditlog")
MIDDLEWARE.append("auditlog.middleware.AuditlogMiddleware")

View File

@ -247,7 +247,7 @@ class TestAuditLogChecks(TestCase):
"""
introspect_mock = mock.MagicMock()
introspect_mock.introspection.table_names.return_value = ["auditlog_logentry"]
with override_settings(AUDIT_LOG_ENABLED=False):
with override_settings(AUDIT_LOG_DISABLED=True):
with mock.patch.dict(
"paperless.checks.connections",
{"default": introspect_mock},
@ -259,9 +259,6 @@ class TestAuditLogChecks(TestCase):
msg = msgs[0]
self.assertIn(
(
"auditlog table was found but PAPERLESS_AUDIT_LOG_ENABLED"
" is not active."
),
("auditlog table was found but AUDIT_LOG_DISABLED is active."),
msg.msg,
)

View File

@ -17,8 +17,8 @@ omit =
[coverage:report]
exclude_also =
if settings.AUDIT_LOG_ENABLED:
if AUDIT_LOG_ENABLED:
if settings.AUDIT_LOG_DISABLED:
if AUDIT_LOG_DISABLED:
if TYPE_CHECKING:
[mypy]