From bf4de6f4c3a9a3422c48b20c4c8775fe99ae99f4 Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri, 4 Sep 2026 15:08:19 -0700 Subject: [PATCH] Ok add externally_configured_fields --- src/documents/tests/test_api_app_config.py | 29 +++++++++++++++++++++- src/paperless/serialisers.py | 8 ++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/documents/tests/test_api_app_config.py b/src/documents/tests/test_api_app_config.py index b98c0d7da..0ca6f4412 100644 --- a/src/documents/tests/test_api_app_config.py +++ b/src/documents/tests/test_api_app_config.py @@ -35,7 +35,8 @@ class TestApiAppConfig(DirectoriesMixin, APITestCase): THEN: - Existing config """ - response = self.client.get(self.ENDPOINT, format="json") + with patch.dict("os.environ", {}, clear=True): + response = self.client.get(self.ENDPOINT, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -45,6 +46,7 @@ class TestApiAppConfig(DirectoriesMixin, APITestCase): response.data[0], { "id": 1, + "externally_configured_variables": [], "output_type": None, "pages": None, "language": None, @@ -91,6 +93,31 @@ class TestApiAppConfig(DirectoriesMixin, APITestCase): }, ) + def test_api_get_config_reports_external_configuration_without_values(self) -> None: + with patch.dict( + "os.environ", + { + "PAPERLESS_OCR_LANGUAGE": "eng", + "PAPERLESS_REMOTE_OCR_API_KEY": "secret-value", + "PAPERLESS_FUTURE_SETTING": "future-value", + "UNRELATED_SETTING": "unrelated-value", + }, + clear=True, + ): + response = self.client.get(self.ENDPOINT, format="json") + + self.assertCountEqual( + response.data[0]["externally_configured_variables"], + [ + "PAPERLESS_FUTURE_SETTING", + "PAPERLESS_OCR_LANGUAGE", + "PAPERLESS_REMOTE_OCR_API_KEY", + ], + ) + self.assertNotContains(response, "secret-value") + self.assertNotContains(response, "future-value") + self.assertNotContains(response, "UNRELATED_SETTING") + def test_api_get_ui_settings_with_config(self) -> None: """ GIVEN: diff --git a/src/paperless/serialisers.py b/src/paperless/serialisers.py index 38baf1be5..f7cfc3d45 100644 --- a/src/paperless/serialisers.py +++ b/src/paperless/serialisers.py @@ -1,4 +1,5 @@ import logging +import os from io import BytesIO import magic @@ -212,6 +213,7 @@ class ProfileSerializer(PasswordValidationMixin, serializers.ModelSerializer[Use class ApplicationConfigurationSerializer( serializers.ModelSerializer[ApplicationConfiguration], ): + externally_configured_variables = serializers.SerializerMethodField() user_args = serializers.JSONField(binary=True, allow_null=True) barcode_tag_mapping = serializers.JSONField(binary=True, allow_null=True) llm_api_key = ObfuscatedPasswordField( @@ -227,6 +229,12 @@ class ApplicationConfigurationSerializer( OBFUSCATED_FIELDS = ("llm_api_key", "remote_ocr_api_key") + def get_externally_configured_variables( + self, + instance: ApplicationConfiguration, + ) -> list[str]: + return sorted(name for name in os.environ if name.startswith("PAPERLESS_")) + def run_validation(self, data): # Empty strings treated as None to avoid unexpected behavior if "user_args" in data and data["user_args"] == "":