Repository: paperless-ngx/paperless-ngx

Issue:
[BUG] 403 Forbidden when accessing auditlog with superuser
### Description

I hope I didnt miss any discussions regarding this, but I noticed that even an admin cannot see the history of a document they dont own. They get the infinite loading circle and the browser logs show a 403 Forbidden "insufficient permissions" on the /history endpoint.

![image](https://github.com/paperless-ngx/paperless-ngx/assets/36535726/2397296c-8f32-48c5-bef1-d59c963a66ae)
![image](https://github.com/paperless-ngx/paperless-ngx/assets/36535726/47502eca-1322-48ba-b2e3-ccff50836d38)

### Steps to reproduce

1. Log in as a superuser
2. Try to access the auditlog of a document that is owned by another user

### Webserver logs

```bash
---
```


### Browser logs

```bash
see screenshots above
```


### Paperless-ngx version

2.8.2

### Host OS

Synology DSM 7.2 | x86_64

### Installation method

Docker - official image

### Browser

_No response_

### Configuration changes

_No response_

### Other

_No response_

### Please confirm the following

- [X] I believe this issue is a bug that affects all users of Paperless-ngx, not something specific to my installation.
- [X] I have already searched for relevant existing issues and discussions before opening this report.
- [X] I have updated the title field above with a concise description.


Discussion:

Resolving patch:
diff --git a/src/documents/views.py b/src/documents/views.py
--- a/src/documents/views.py
+++ b/src/documents/views.py
@@ -767,7 +767,9 @@ def history(self, request, pk=None):
         try:
             doc = Document.objects.get(pk=pk)
             if not request.user.has_perm("auditlog.view_logentry") or (
-                doc.owner is not None and doc.owner != request.user
+                doc.owner is not None
+                and doc.owner != request.user
+                and not request.user.is_superuser
             ):
                 return HttpResponseForbidden(
                     "Insufficient permissions",


Test patch:
diff --git a/src/documents/tests/test_api_documents.py b/src/documents/tests/test_api_documents.py
--- a/src/documents/tests/test_api_documents.py
+++ b/src/documents/tests/test_api_documents.py
@@ -423,16 +423,18 @@ def test_document_history_action_disabled(self):
     def test_document_history_insufficient_perms(self):
         """
         GIVEN:
-            - Audit log is disabled
+            - Audit log is enabled
         WHEN:
-            - Document is updated
-            - Audit log is requested
+            - History is requested without auditlog permissions
+            - Or is requested as superuser on document with another owner
         THEN:
-            - Audit log returns HTTP 400 Bad Request
+            - History endpoint returns HTTP 403 Forbidden
+            - History is returned
         """
+        # No auditlog permissions
         user = User.objects.create_user(username="test")
         user.user_permissions.add(*Permission.objects.filter(codename="view_document"))
-        self.client.force_login(user=user)
+        self.client.force_authenticate(user=user)
         doc = Document.objects.create(
             title="First title",
             checksum="123",
@@ -443,6 +445,19 @@ def test_document_history_insufficient_perms(self):
         response = self.client.get(f"/api/documents/{doc.pk}/history/")
         self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
 
+        # superuser
+        user.is_superuser = True
+        user.save()
+        user2 = User.objects.create_user(username="test2")
+        doc2 = Document.objects.create(
+            title="Second title",
+            checksum="456",
+            mime_type="application/pdf",
+            owner=user2,
+        )
+        response = self.client.get(f"/api/documents/{doc2.pk}/history/")
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+
     def test_document_filters(self):
         doc1 = Document.objects.create(
             title="none1",