You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by el...@apache.org on 2026/09/02 22:08:00 UTC

(superset) branch master updated: fix(gsheets): catch JSONDecodeError in validate_parameters for malformed service_account_info (#43772)

This is an automated email from the ASF dual-hosted git repository.

eschutho pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new a81c0f67739 fix(gsheets): catch JSONDecodeError in validate_parameters for malformed service_account_info (#43772)
a81c0f67739 is described below

commit a81c0f677393656e61e436f5bd51d675b757df58
Author: Elizabeth Thompson <es...@gmail.com>
AuthorDate: Wed Sep 2 15:07:53 2026 -0700

    fix(gsheets): catch JSONDecodeError in validate_parameters for malformed service_account_info (#43772)
    
    Co-authored-by: Claude Opus 4.8 <no...@anthropic.com>
---
 superset/db_engine_specs/gsheets.py              | 17 ++++++++++++-
 tests/unit_tests/db_engine_specs/test_gsheets.py | 31 ++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/superset/db_engine_specs/gsheets.py b/superset/db_engine_specs/gsheets.py
index c932299f090..7fd1ac1156b 100644
--- a/superset/db_engine_specs/gsheets.py
+++ b/superset/db_engine_specs/gsheets.py
@@ -393,7 +393,22 @@ class GSheetsEngineSpec(ShillelaghEngineSpec):
         # On create the encrypted credentials are a string,
         # at all other times they are a dict
         if isinstance(encrypted_credentials, str):
-            encrypted_credentials = json.loads(encrypted_credentials)
+            try:
+                encrypted_credentials = json.loads(encrypted_credentials)
+            except json.JSONDecodeError:
+                errors.append(
+                    SupersetError(
+                        message=(
+                            "The service account credentials are not valid JSON. "
+                            "Please check that the field contains a valid service "
+                            "account key."
+                        ),
+                        error_type=SupersetErrorType.INVALID_PAYLOAD_FORMAT_ERROR,
+                        level=ErrorLevel.ERROR,
+                        extra={"invalid": ["service_account_info"]},
+                    ),
+                )
+                return errors
 
         # We need a subject in case domain wide delegation is set, otherwise the
         # check will fail. This means that the admin will be able to add sheets
diff --git a/tests/unit_tests/db_engine_specs/test_gsheets.py b/tests/unit_tests/db_engine_specs/test_gsheets.py
index fc77cf57732..4a156a0f5d6 100644
--- a/tests/unit_tests/db_engine_specs/test_gsheets.py
+++ b/tests/unit_tests/db_engine_specs/test_gsheets.py
@@ -110,6 +110,37 @@ def test_validate_parameters_no_catalog(mocker: MockerFixture) -> None:
     ]
 
 
+def test_validate_parameters_malformed_credentials(mocker: MockerFixture) -> None:
+    from superset.db_engine_specs.gsheets import (
+        GSheetsEngineSpec,
+        GSheetsPropertiesType,
+    )
+
+    g = mocker.patch("superset.db_engine_specs.gsheets.g")
+    g.user.email = "admin@example.org"
+
+    properties: GSheetsPropertiesType = {
+        "parameters": {
+            "service_account_info": "{not valid json",
+            "catalog": {},
+        },
+        "catalog": {},
+    }
+    errors = GSheetsEngineSpec.validate_parameters(properties)
+    assert errors == [
+        SupersetError(
+            message=(
+                "The service account credentials are not valid JSON. "
+                "Please check that the field contains a valid service "
+                "account key."
+            ),
+            error_type=SupersetErrorType.INVALID_PAYLOAD_FORMAT_ERROR,
+            level=ErrorLevel.ERROR,
+            extra={"invalid": ["service_account_info"]},
+        ),
+    ]
+
+
 def test_validate_parameters_simple_with_in_root_catalog(mocker: MockerFixture) -> None:
     from superset.db_engine_specs.gsheets import (
         GSheetsEngineSpec,