Repository: paperless-ngx/paperless-ngx

Issue:
[BUG] OCR arguments set in UI are not parsed correctly
### Description

Attempting to set OCR arguments via the configuration page in the admin panel results in the following error message when running OCR on the next document:
`[WARNING] [paperless.parsing.tesseract] There is an issue with PAPERLESS_OCR_USER_ARGS, so they will not be used. Error: 'str' object is not a mapping`
I tried to set the "invalidate_digital_signatures" flag as shown below. The same setting was applied correctly when set as an environment variable. I did not test other flags, but from the error message it seems like any flag would fail.

<img width="450" alt="screenshot" src="https://github.com/paperless-ngx/paperless-ngx/assets/90611500/e358b707-3f30-4cf0-ba15-efc68440703c">


### Steps to reproduce

1. On the configuration page set {"invalidate_digital_signatures": true} as OCR arguments and save
2. Upload a document to trigger OCR

### Webserver logs

```bash
2024-01-07 20:21:33 [2024-01-07 20:21:33,345] [INFO] [celery.worker.strategy] Task documents.tasks.consume_file[07a56007-87e6-4baa-885f-f6ee86e272d0] received
2024-01-07 20:21:33 [2024-01-07 20:21:33,390] [INFO] [paperless.consumer] Consuming document_with_signature.pdf
2024-01-07 20:21:33 [2024-01-07 20:21:33,520] [WARNING] [paperless.parsing.tesseract] There is an issue with PAPERLESS_OCR_USER_ARGS, so they will not be used. Error: 'str' object is not a mapping
2024-01-07 20:21:33 [2024-01-07 20:21:33,626] [WARNING] [paperless.parsing.tesseract] Encountered an error while running OCR: Input PDF has a digital signature. OCR would alter the document,
2024-01-07 20:21:33 invalidating the signature.
2024-01-07 20:21:33 . Attempting force OCR to get the text.
2024-01-07 20:21:33 [2024-01-07 20:21:33,629] [WARNING] [paperless.parsing.tesseract] There is an issue with PAPERLESS_OCR_USER_ARGS, so they will not be used. Error: 'str' object is not a mapping
2024-01-07 20:21:33 [2024-01-07 20:21:33,733] [ERROR] [paperless.consumer] Error occurred while consuming document document_with_signature.pdf: DigitalSignatureError: Input PDF has a digital signature. OCR would alter the document,
2024-01-07 20:21:33 invalidating the signature.
2024-01-07 20:21:33 Traceback (most recent call last):
2024-01-07 20:21:33   File "/usr/src/paperless/src/paperless_tesseract/parsers.py", line 353, in parse
2024-01-07 20:21:33     ocrmypdf.ocr(**args)
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/ocrmypdf/api.py", line 375, in ocr
2024-01-07 20:21:33     return run_pipeline(options=options, plugin_manager=plugin_manager)
2024-01-07 20:21:33            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipelines/ocr.py", line 225, in run_pipeline
2024-01-07 20:21:33     return _run_pipeline(options, plugin_manager)
2024-01-07 20:21:33            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipelines/ocr.py", line 189, in _run_pipeline
2024-01-07 20:21:33     validate_pdfinfo_options(context)
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipeline.py", line 202, in validate_pdfinfo_options
2024-01-07 20:21:33     raise DigitalSignatureError()
2024-01-07 20:21:33 ocrmypdf.exceptions.DigitalSignatureError: Input PDF has a digital signature. OCR would alter the document,
2024-01-07 20:21:33 invalidating the signature.
2024-01-07 20:21:33 
2024-01-07 20:21:33 
2024-01-07 20:21:33 During handling of the above exception, another exception occurred:
2024-01-07 20:21:33 
2024-01-07 20:21:33 Traceback (most recent call last):
2024-01-07 20:21:33   File "/usr/src/paperless/src/paperless_tesseract/parsers.py", line 404, in parse
2024-01-07 20:21:33     ocrmypdf.ocr(**args)
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/ocrmypdf/api.py", line 375, in ocr
2024-01-07 20:21:33     return run_pipeline(options=options, plugin_manager=plugin_manager)
2024-01-07 20:21:33            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipelines/ocr.py", line 225, in run_pipeline
2024-01-07 20:21:33     return _run_pipeline(options, plugin_manager)
2024-01-07 20:21:33            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipelines/ocr.py", line 189, in _run_pipeline
2024-01-07 20:21:33     validate_pdfinfo_options(context)
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipeline.py", line 202, in validate_pdfinfo_options
2024-01-07 20:21:33     raise DigitalSignatureError()
2024-01-07 20:21:33 ocrmypdf.exceptions.DigitalSignatureError: Input PDF has a digital signature. OCR would alter the document,
2024-01-07 20:21:33 invalidating the signature.
2024-01-07 20:21:33 
2024-01-07 20:21:33 
2024-01-07 20:21:33 The above exception was the direct cause of the following exception:
2024-01-07 20:21:33 
2024-01-07 20:21:33 Traceback (most recent call last):
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/asgiref/sync.py", line 349, in main_wrap
2024-01-07 20:21:33     raise exc_info[1]
2024-01-07 20:21:33   File "/usr/src/paperless/src/documents/consumer.py", line 446, in try_consume_file
2024-01-07 20:21:33     document_parser.parse(self.working_copy, mime_type, self.filename)
2024-01-07 20:21:33   File "/usr/src/paperless/src/paperless_tesseract/parsers.py", line 416, in parse
2024-01-07 20:21:33     raise ParseError(f"{e.__class__.__name__}: {e!s}") from e
2024-01-07 20:21:33 documents.parsers.ParseError: DigitalSignatureError: Input PDF has a digital signature. OCR would alter the document,
2024-01-07 20:21:33 invalidating the signature.
2024-01-07 20:21:33 
2024-01-07 20:21:33 [2024-01-07 20:21:33,758] [ERROR] [celery.app.trace] Task documents.tasks.consume_file[07a56007-87e6-4baa-885f-f6ee86e272d0] raised unexpected: ConsumerError('document_with_signature.pdf: Error occurred while consuming document document_with_signature.pdf: DigitalSignatureError: Input PDF has a digital signature. OCR would alter the document,\ninvalidating the signature.\n')
2024-01-07 20:21:33 Traceback (most recent call last):
2024-01-07 20:21:33   File "/usr/src/paperless/src/paperless_tesseract/parsers.py", line 353, in parse
2024-01-07 20:21:33     ocrmypdf.ocr(**args)
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/ocrmypdf/api.py", line 375, in ocr
2024-01-07 20:21:33     return run_pipeline(options=options, plugin_manager=plugin_manager)
2024-01-07 20:21:33            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipelines/ocr.py", line 225, in run_pipeline
2024-01-07 20:21:33     return _run_pipeline(options, plugin_manager)
2024-01-07 20:21:33            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipelines/ocr.py", line 189, in _run_pipeline
2024-01-07 20:21:33     validate_pdfinfo_options(context)
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipeline.py", line 202, in validate_pdfinfo_options
2024-01-07 20:21:33     raise DigitalSignatureError()
2024-01-07 20:21:33 ocrmypdf.exceptions.DigitalSignatureError: Input PDF has a digital signature. OCR would alter the document,
2024-01-07 20:21:33 invalidating the signature.
2024-01-07 20:21:33 
2024-01-07 20:21:33 
2024-01-07 20:21:33 During handling of the above exception, another exception occurred:
2024-01-07 20:21:33 
2024-01-07 20:21:33 Traceback (most recent call last):
2024-01-07 20:21:33   File "/usr/src/paperless/src/paperless_tesseract/parsers.py", line 404, in parse
2024-01-07 20:21:33     ocrmypdf.ocr(**args)
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/ocrmypdf/api.py", line 375, in ocr
2024-01-07 20:21:33     return run_pipeline(options=options, plugin_manager=plugin_manager)
2024-01-07 20:21:33            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipelines/ocr.py", line 225, in run_pipeline
2024-01-07 20:21:33     return _run_pipeline(options, plugin_manager)
2024-01-07 20:21:33            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipelines/ocr.py", line 189, in _run_pipeline
2024-01-07 20:21:33     validate_pdfinfo_options(context)
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipeline.py", line 202, in validate_pdfinfo_options
2024-01-07 20:21:33     raise DigitalSignatureError()
2024-01-07 20:21:33 ocrmypdf.exceptions.DigitalSignatureError: Input PDF has a digital signature. OCR would alter the document,
2024-01-07 20:21:33 invalidating the signature.
2024-01-07 20:21:33 
2024-01-07 20:21:33 
2024-01-07 20:21:33 The above exception was the direct cause of the following exception:
2024-01-07 20:21:33 
2024-01-07 20:21:33 Traceback (most recent call last):
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/asgiref/sync.py", line 349, in main_wrap
2024-01-07 20:21:33     raise exc_info[1]
2024-01-07 20:21:33   File "/usr/src/paperless/src/documents/consumer.py", line 446, in try_consume_file
2024-01-07 20:21:33     document_parser.parse(self.working_copy, mime_type, self.filename)
2024-01-07 20:21:33   File "/usr/src/paperless/src/paperless_tesseract/parsers.py", line 416, in parse
2024-01-07 20:21:33     raise ParseError(f"{e.__class__.__name__}: {e!s}") from e
2024-01-07 20:21:33 documents.parsers.ParseError: DigitalSignatureError: Input PDF has a digital signature. OCR would alter the document,
2024-01-07 20:21:33 invalidating the signature.
2024-01-07 20:21:33 
2024-01-07 20:21:33 
2024-01-07 20:21:33 The above exception was the direct cause of the following exception:
2024-01-07 20:21:33 
2024-01-07 20:21:33 Traceback (most recent call last):
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/celery/app/trace.py", line 477, in trace_task
2024-01-07 20:21:33     R = retval = fun(*args, **kwargs)
2024-01-07 20:21:33                  ^^^^^^^^^^^^^^^^^^^^
2024-01-07 20:21:33   File "/usr/local/lib/python3.11/site-packages/celery/app/trace.py", line 760, in __protected_call__
2024-01-07 20:21:33     return self.run(*args, **kwargs)
2024-01-07 20:21:33            ^^^^^^^^^^^^^^^^^^^^^^^^^
2024-01-07 20:21:33   File "/usr/src/paperless/src/documents/tasks.py", line 171, in consume_file
2024-01-07 20:21:33     document = Consumer().try_consume_file(
2024-01-07 20:21:33                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-01-07 20:21:33   File "/usr/src/paperless/src/documents/consumer.py", line 474, in try_consume_file
2024-01-07 20:21:33     self._fail(
2024-01-07 20:21:33   File "/usr/src/paperless/src/documents/consumer.py", line 116, in _fail
2024-01-07 20:21:33     raise ConsumerError(f"{self.filename}: {log_message or message}") from exception
2024-01-07 20:21:33 documents.consumer.ConsumerError: document_with_signature.pdf: Error occurred while consuming document document_with_signature.pdf: DigitalSignatureError: Input PDF has a digital signature. OCR would alter the document,
2024-01-07 20:21:33 invalidating the signature.
2024-01-07 20:21:33
```


### Browser logs

_No response_

### Paperless-ngx version

2.3.1

### Host OS

Windows 11 Pro x64

### Installation method

Docker - official image

### Browser

Firefox PWA

### Configuration changes

PAPERLESS_OCR_LANGUAGE: deu

### 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:
Ah, I think wires got crossed, https://github.com/paperless-ngx/paperless-ngx/blob/d54de65bb7ec563fbf16734f54032e2d86c95bcd/src/paperless_tesseract/tests/test_parser_custom_settings.py#L223 isnt really how the frontend passes them, it passes the whole thing as a (valid JSON) string, so I guess backend needs to parse them. @stumpylog Is JSONField is supposed to do that for us or does the frontend need to send it as JSON object?

Resolving patch:
diff --git a/src/paperless/serialisers.py b/src/paperless/serialisers.py
--- a/src/paperless/serialisers.py
+++ b/src/paperless/serialisers.py
@@ -1,3 +1,5 @@
+import logging
+
 from django.contrib.auth.models import Group
 from django.contrib.auth.models import Permission
 from django.contrib.auth.models import User
@@ -5,6 +7,8 @@
 
 from paperless.models import ApplicationConfiguration
 
+logger = logging.getLogger("paperless.settings")
+
 
 class ObfuscatedUserPasswordField(serializers.Field):
     """
@@ -118,6 +122,8 @@ class Meta:
 
 
 class ApplicationConfigurationSerializer(serializers.ModelSerializer):
+    user_args = serializers.JSONField(binary=True)
+
     class Meta:
         model = ApplicationConfiguration
         fields = "__all__"


Test patch: